2013-05-20 116 views
0

嗨, 我是JPA的新手,我在oneToMany關係持久化中遇到了性能問題。 實體和控制器已由netbeans生成。 看看下面的代碼。 當堅持一個人, JPA - 堅持一對多的性能

profileId.getPersonSet().add(person);
需要大約45次,因爲我的數據庫包含約16000人。太多了 !我怎麼能改善這個?

<pre><code> 
    public class Profile implements Serializable { 
     private static final long serialVersionUID = 1L; 
     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 
     @Basic(optional = false) 
     @Column(name = "profile_id", nullable = false) 
     private Integer profileId; 
     @Basic(optional = false) 
     @Column(nullable = false, length = 60) 
     private String label; 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "profileId", fetch = FetchType.EAGER) 
     private Set<Person> personSet; 

     public Profile() { 
     } 
     ............. 
    </code></pre> 

    <pre><code> 
    public class Person implements Serializable { 
     private static final long serialVersionUID = 1L; 
     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 
     @Basic(optional = false) 
     @Column(name = "person_id", nullable = false) 
     private Long personId; 
     @Basic(optional = false) 
     @Column(name = "last_name", nullable = false, length = 60) 
     private String lastName; 
     @Basic(optional = false) 
     @Column(name = "first_name", nullable = false, length = 60) 
     private String firstName; 
     @Basic(optional = false) 
     @Column(nullable = false) 
     @Temporal(TemporalType.DATE) 
     private Date birthday; 
     @Column(length = 60) 
     private String email; 
     @Column(length = 60) 
     private String phone; 
     @Column(name = "mobile_phone", length = 60) 
     private String mobilePhone; 
     @Column(length = 60) 
     private String company; 
     @JoinColumn(name = "profile_id", referencedColumnName = "profile_id", nullable = false) 
     @ManyToOne(optional = false, fetch = FetchType.LAZY) 
     private Profile profileId; 
     @OneToOne(cascade = CascadeType.ALL, mappedBy = "personId", fetch = FetchType.LAZY) 
     .............. 

    </code></pre> 

    <pre><code> 
    public class PersonJpaController implements Serializable { 

     public PersonJpaController(EntityManagerFactory emf) { 
      this.emf = emf; 
     } 
     private EntityManagerFactory emf = null; 

     public EntityManager getEntityManager() { 
      return emf.createEntityManager(); 
     } 

     public void create(Person person) { 
      EntityManager em = null; 
      try { 
       em = getEntityManager(); 
       em.getTransaction().begin(); 
       Profile profileId = person.getProfileId(); 
       if (profileId != null) { 
        profileId = em.getReference(profileId.getClass(), profileId.getProfileId()); 
        person.setProfileId(profileId); 
       } 
       .......................... 
       em.persist(person); 
       if (profileId != null) { 
        profileId.getPersonSet().add(person); 
        profileId = em.merge(profileId); 
       } 


    .................... 
</code></pre> 

回答

0

只需拆除的最後幾行:

if (profileId != null) { 
    profileId.getPersonSet().add(person); 
    profileId = em.merge(profileId); 
} 

這些行強制JPA加載配置文件,加載其所有的人,和新的人加入到集合中。這是不需要的,因爲該協會的所有者是Person。這就是說,如果一個配置文件有太多的人加載它們都是一個問題,那麼該關聯應該被建模爲一個單向的ManyToOne關聯。

0

將人員設置爲LAZY或將其全部刪除,因爲它似乎太大而無法加載。

也將類型更改爲列表。如果您使用的是EclipseLink並且已正確編織,那麼在add()調用中不會加載懶惰列表。

不知道你爲什麼調用merge()這不應該是必需的,除非它是分離的。