0

こんにちは、私は 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>
4

2 に答える 2

0

personSet を LAZY にするか、大きすぎてロードしたくないので、すべて削除します。

また、タイプをリストに変更します。EclipseLink を使用していて、ウィービングが正しく有効になっている場合、LAZY リストは add() 呼び出しでロードされません。

merge() を呼び出す理由がわかりません。分離されていない限り、これは必要ありません。

于 2013-05-21T15:21:39.610 に答える
0

最後の数行を削除するだけです。

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

これらの行により、JPA はプロファイルをロードし、そのすべての人物をロードし、新しい人物をコレクションに追加するよう強制されます。関連付けの所有者は Person であるため、これは必要ありません。

とはいえ、プロファイルに非常に多くの人がいて、すべてをロードするのが問題である場合、関連付けはおそらく一方向の ManyToOne 関連付けとしてモデル化する必要があります。

于 2013-05-20T11:41:24.070 に答える