0

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

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

2 回答 2

0

使 personSet LAZY 或将其全部删除,因为它似乎太大而无法加载。

还将类型更改为列表。如果您使用的是 EclipseLink 并正确启用了编织,则不会在 add() 调用上加载 LAZY List。

不知道为什么你调用 merge() 这不应该是必需的,除非它是分离的。

于 2013-05-21T15:21:39.610 回答
0

Simply remove the last few lines:

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

These lines force JPA to load the profile, load all its persons, and add the new person to the collection. It's not needed, since the owner of the association is Person.

That said, if a profile has so many persons that it's a problem to load them all, the association should probably be modeled as a unidirectional ManyToOne association.

于 2013-05-20T11:41:24.070 回答