JPA: How to get Id after persist in standalone java app
Solution 1
Here is my answer. Tested
When mapping your Id, switch from what I have above, which is
@Id
@Basic(optional = false)
@Column(name = "ID")
private Long id;
to
@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;
...
}
Since I use microsoft SQL server, I have to use @TableGenerator
. More information can be found here http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Table_sequencing
Solution 2
Try adding a @GeneratedValue
on your id field.
Solution 3
I know it's not a persist but the merge will do the same thing more simply. I wrap my persist in an actual merge operation which will save the entity if it does not exist.
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();
}
Solution 4
As I found on this post the EntityManager have a method called refresh that will update your object after you persist him.
So your code will probably looks like this:
public <T> T create(T t) {
em.getTransaction().begin();
em.persist(t);
em.refresh(t);
em.flush();
em.getTransaction().commit();
return t;
}
I haven't tested this, so I'm not sure where exactly to put the refresh method call, there, after the commit, after the flush, etc.
Hope it can help you.
Good luck.
Thang Pham
Updated on June 04, 2022Comments
-
Thang Pham almost 2 years
This is a standalone java application, not web application. So when I persist the object like this
public <T> T create(T t) { em.getTransaction().begin(); em.persist(t); em.flush(); em.getTransaction().commit(); return t; }
The
id
inside theT t
object is still null, even though a new row with correct data and id is created correctly inside the database. Usually in my web app that utilize@EJB
, theid
available right after I persist, since it persist the entity object into my persistence context, I am not sure if I have my persistence context here?This is how I mapped my id inside my @Entity Class
@Id @Basic(optional = false) @Column(name = "ID") private Long id;
also I make the id of this table in the database
AUTO_INCREMENT
, like thisCREATE TABLE Config ( ID int NOT NULL AUTO_INCREMENT, PRIMARY KEY (ID) )
This is how I obtain my EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("CorePU"); em = emf.createEntityManager();
Here is what inside my
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>
Please help, I am not sure what I did wrong here.