2017-09-19 15 views
0

コレクション内に1つの分離された子エンティティを持つエンティティをマージすることに問題があります。これは、例外をスロー: org.hibernate.PersistentObjectException:永続化するために渡されたデタッチエンティティ:com.adastragrp.cmsms.data.SeedNumber分離された子を持つHibernateのマージ親

あなたは、私がDBから、いくつかのキューを取得、この「テスト()」メソッドでは見ることができますその子供たちを連れて行く。それらは "saveQueue()"メソッドに送られるときに切り離された状態にあります。この方法では、それらを他のキューに追加します。このキューをマージすると、hibernateは例外をスローします。

どうすればいいですか?答えや説明をありがとう。

private void test() { 
     List<SeedNumber> list = loadQueue(); 
     saveQueue(list); 
    } 

    @Transactional 
    private List<SeedNumber> loadQueue() { 
     return queueDAO.find("SECONDARY").getSeedNumbers(); 
    } 

    @Transactional 
    private void saveQueue(List<SeedNumber> detachedSeeds) { 
     Queue q = queueDAO.find("DEFAULT"); 

     List<SeedNumber> seeds = new ArrayList<>(); 
     SeedNumber sn = new SeedNumber(); 
     sn.setPhoneNumber("123456"); 
     sn.setQueue(q); 
     seeds.add(sn); 
     for(SeedNumber s : detachedSeeds) { 
      s.setQueue(q); 
      seeds.add(s); 
     } 

     q.setSeedNumbers(seeds);    

     q = queueDAO.save(q); 
    } 

DAOコード:

public Queue save(Queue entity) { 
    if (entity == null) { 
     LOG.info("queue is null"); 
     return null; 
    } 
    if (getEntityManager().contains(entity)) { 
     return entity; 
    } 

    entity = getEntityManager().merge(entity); 

    return entity; 
} 

これは、親クラスである:

@Entity 
@Table(name = "CMSMS_QUEUE") 
public class Queue { 

    @Id 
    @Column(name = "ID", length = 40) 
    private String id; 

    @OneToMany(mappedBy = "queue", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private List<SeedNumber> seedNumbers; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public List<SeedNumber> getSeedNumbers() { 
     return seedNumbers; 
    } 

    public void setSeedNumbers(List<SeedNumber> seedNumbers) { 
     this.seedNumbers = seedNumbers; 
    } 
} 

これは、子クラスである:

@Entity 
@Table(name = "CMSMS_SEED_NUMBER") 
@SequenceGenerator(name = "SeedNumberSeq", sequenceName = "CMSMS_SEED_NUMBER_SEQ", allocationSize = 1) 
public class SeedNumber { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SeedNumberSeq") 
    @Column(name = "ID") 
    private Long id; 

    @Column(name = "PHONE_NUMBER") 
    private String phoneNumber; 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "QUEUE_ID") 
    private Queue queue; 


    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public String getPhoneNumber() { 
     return phoneNumber; 
    } 

    public void setPhoneNumber(String phoneNumber) { 
     this.phoneNumber = phoneNumber; 
    } 

    public Queue getQueue() { 
     return queue; 
    } 

    public void setQueue(Queue queue) { 
     this.queue = queue; 
    } 


} 

答えて

1

私は次のコードを考えます問題がある:

if (getEntityManager().contains(entity)) { 
    return entity; 
} 

entity = getEntityManager().merge(entity); 

return entity; 

あなたはcascade=MERGEはシード番号のリストに伝播したい場合は、mergeへの呼び出しをスキップするべきではありません。

IMHO、より明確に解決策はそうのようなsaveQueueを実装するために、次のようになります。注意点として

private void saveQueue(List<SeedNumber> detachedSeeds) { 
    Queue queue = queueDAO.find("DEFAULT"); 

    SeedNumber sn = new SeedNumber(); 
    sn.setPhoneNumber("123456"); 
    sn.setQueue(q); 
    seedNumberDao.saveSeed(sn); 
    for (SeedNumber seed : detachedSeeds) { 
     seed.setQueue(queue); 
     seedNumberDao.saveSeed(seed); 
    } 
} 

、効果はありませんプライベートメソッドに@Transactionalを置きます。

+0

はい、そうです。オブジェクトがすでにPersistanceContextに入っているときにマージをスキップしたことはわかりませんでした。どうもありがとう! @Transactionalアノテーションに関しては、Maven AspectJプラグインを使用しているので、プライベートメソッドでも動作します。 – Gobanit

関連する問題