2013-07-03 86 views
0

我的应用程序在域级别的值对象之间使用了很多OneToMany和OneToOne引用,其中大多数是实体,或者是超类或者是某个子类。我想提供我的应用程序一致的(尚易)的方式来保存这些实例和保存(实际的方法)是这样JPA OneToOne和OneToMany实体实例/创建

@Transactional 
public void save(Post post){ 

    try{ 
     JPA.em().persist(post); 
    }catch (EntityExistsException eee){ 
     JPA.em().merge(post); 
    }catch(ConstraintViolationException cve){ 
     JPA.em().refresh(post); 
    } 
} 

现在的问题是如何正确实例化的对象,并在CascadeType的哪些战略选择,我会喜欢保存嵌套的对象时保存一个对象与其他实体的引用,它现在工作,但只有第一次,之后,我得到一个Unique index or primary key violation给定SQL insert into Utente (passwd, DTYPE, username) values (?, 'Redattore', ?) [23505-168] .Clearly我JPA提供商(休眠3.6.9)没有不更新现有的行,而是试图插入在DB.Here一个新的条目是一些类,我使用:

@Entity 
@Table 
public class Post extends Domanda { 

@Column(nullable = false) 
private String nome; 

@OneToMany(cascade = CascadeType.ALL) 
private List<Commento> commenti; 

@OneToMany(cascade = CascadeType.ALL) 
private List<Risorsa> risorse; 

@OneToOne(cascade = CascadeType.ALL) 
private NodoApprendimento nodo; 

@Column 
private int visibilità; 

@Column 
private boolean isDraft; 

邮报引用由几个类中,我有:

@Entity 
public abstract class Partecipante extends Utente{ 


@OneToMany(cascade = CascadeType.ALL, 
      fetch = FetchType.LAZY) 
private Set<Post> contributi; 

然后,我想知道在数据库初始化的正确方法和persisteORupdate这些引用的对象,在此先感谢。

回答

0

这不是提供者问题,而是使用问题。当您调用persist时,JPA不要求提供者立即执行插入 - 他们通常会延迟刷新或提交时间。所以在大多数情况下你不会得到一个EntityExistsException。无论哪种方式,交易状态应标记为回滚 - 你不应该依靠坚持来确定是否应该调用合并。既可以调用em.find,也可以只调用实体的em.merge,并允许JPA提供程序确定它是否应该为您插入或更新。

+0

另请注意,由于不需要在flush/commit之前发布语句,因此您也不会捕获ConstraintViolationException。您可能不得不在事务中显式调用em.flush(),以确保语句被发出并导致异常被抛出。 – Chris