2012-04-05 59 views
4

这是一个独立的Java应用程序,而不是Web应用程序。所以,当我坚持的对象这样JPA:如何在独立Java应用程序中保留ID后

public <T> T create(T t) { 
    em.getTransaction().begin(); 
    em.persist(t); 
    em.flush(); 
    em.getTransaction().commit(); 
    return t; 
} 

idT t对象内仍无效,即使新行正确的数据,ID是数据库中正确创建。通常在我的网络应用程序中,使用@EJB,id在我坚持后立即可用,因为它将实体对象持久化到我的持久化上下文中,我不确定在这里是否有我的持久化上下文?

这是我映射我的ID我@Entity类中

@Id 
@Basic(optional = false) 
@Column(name = "ID") 
private Long id; 

也是我做这个表的id在数据库AUTO_INCREMENT,这样

CREATE TABLE Config 
(
    ID int NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (ID) 
) 

我这是怎么获得我的EntityManager

EntityManagerFactory emf = Persistence.createEntityManagerFactory("CorePU"); 
em = emf.createEntityManager(); 

这里是我的内部persistence.xml

<persistence-unit name="CorePU" transaction-type="RESOURCE_LOCAL"> 
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>  
<class>com.wf.docsys.core.model.Config</class>  
<properties> 
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/XNINFODB"/> 
    <property name="javax.persistence.jdbc.password" value="xxx"/> 
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
    <property name="javax.persistence.jdbc.user" value="xxx"/> 
</properties> 

请帮帮忙,我不知道我做错了什么在这里。

回答

0

这是我的答案。经测试

当从上面我所,这是

@Id 
@Basic(optional = false) 
@Column(name = "ID") 
private Long id; 

@Entity 
public class Person { 
    @Id 
    @TableGenerator(name="TABLE_GEN", table="SEQUENCE_TABLE", pkColumnName="SEQ_NAME", 
     valueColumnName="SEQ_COUNT", pkColumnValue="PERSON_SEQ") 
    @GeneratedValue(strategy=GenerationType.TABLE, generator="TABLE_GEN") 
    private long id; 
    ... 
} 

由于我使用Microsoft SQL Server映射您的ID,开关,我不得不使用@TableGenerator。更多的信息可以在这里找到http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Table_sequencing

4

尝试在您的ID字段中添加@GeneratedValue

1

正如我在this post上发现的那样,EntityManager有一个名为refresh的方法,在你坚持他之后会更新你的对象。

所以,你的代码可能会是这样的:

public <T> T create(T t) { 
    em.getTransaction().begin(); 
    em.persist(t); 
    em.refresh(t); 
    em.flush(); 
    em.getTransaction().commit(); 
    return t; 
} 

我没有测试过这一点,所以我不知道哪儿放刷新方法调用,在那里,提交后,经过冲水等

希望它可以帮助你。

祝你好运。

+4

刷新是不必要的。只要做flush()。这迫使坚持,并因此获得id(一旦用户添加了GeneratedValue注解当然)。 – DataNucleus 2012-04-06 10:59:53

+0

@DataNucleus:是的,我发布了我的答案,因为我不能使用'@ SequenceGenerator',我使用'@ GeneratedValue'@TableGenerator并且它可以工作。但是,每次调用'flush()'都会导致性能问题,DataNucleus? – 2012-04-06 13:05:26

+0

@DataNucleus:flush()为我工作。你应该发布一个答案。如果你精通足够的话也可以解决Thang Pham的表现问题。 – user2316667 2014-06-23 19:11:28

1

我知道这不是坚持,但合并将更简单地做同样的事情。我把我的坚持包裹在一个实际的合并操作中,如果实体不存在,它将保存实体。

public T persist(T obj) { 
    EntityManager em = ThreadLocalPersistenceManager.getEntityManager(); 

    EntityTransaction tx = em.getTransaction(); 
    try { 
     tx.begin(); 
     obj = em.merge(obj); 
    } finally { 
     if (! tx.getRollbackOnly()) { 
      tx.commit(); 
     } 
    } 

    return obj; 
} 


/** 
* This will save the object and return the id of the persisted object. 
* 
* @param obj 
* @return The id of the persisted object. 
*/ 
public Long save(T obj) { 
    persist(obj); 
    return obj.getId(); 
}