JPA - 坚持一对多的表现

时间:2013-05-20 11:30:05

标签: jpa

    嗨,     我是JPA的新手,我在oneToMany关系持久性中遇到了性能问题。     实体和控制器由netbeans生成。     看看下面的代码片段。     当坚持一个人,     

profileId.getPersonSet().add(person);
因为我的数据库包含大约16000人,所以大约需要45个人。实在是太多了 !我怎么能改善这个?

    <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>

2 个答案:

答案 0 :(得分:0)

只需删除最后几行:

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

这些行迫使JPA加载配置文件,加载其所有人员,并将新人添加到集合中。这不是必需的,因为该协会的所有者是人。

也就是说,如果一个配置文件有这么多人,加载它们是一个问题,那么该关联应该被建模为单向ManyToOne关联。

答案 1 :(得分:0)

让person设置LAZY或将它们全部删除,因为它似乎太大而无法加载。

同时将类型更改为List。如果您正在使用EclipseLink并且已正确启用编织,那么将不会在add()调用上加载LAZY List。

不确定为什么要调用merge(),除非它已经分离,否则不应该这样做。