[java] JPA - Returning an auto generated id after persist()

I'm using JPA (EclipseLink) and Spring. Say I have a simple entity with an auto-generated ID:

@Entity
public class ABC implements Serializable {
     @Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)
     private int id;

     // ...
}

In my DAO class, I have an insert method that calls persist() on this entity. I want the method to return the generated ID for the new entity, but when I test it, it returns 0 instead.

public class ABCDao {
    @PersistenceContext
    EntityManager em;

    @Transactional(readOnly=false)
    public int insertABC(ABC abc) {
         em.persist(abc);
         // I WANT TO RETURN THE AUTO-GENERATED ID OF abc
         // HOW CAN I DO IT?
         return abc.id; // ???
    }
}

I also have a service class that wraps the DAO, if that makes a difference:

public class ABCService {
    @Resource(name="ABCDao")
    ABCDao abcDao;

    public int addNewABC(ABC abc) {
         return abcDao.insertABC(abc);
    }
}

This question is related to java jpa

The answer is


Another option compatible to 4.0:

Before committing the changes, you can recover the new CayenneDataObject object(s) from the collection associated to the context, like this:

CayenneDataObject dataObjectsCollection = (CayenneDataObject)cayenneContext.newObjects();

then access the ObjectId for each one in the collection, like:

ObjectId objectId = dataObject.getObjectId();

Finally you can iterate under the values, where usually the generated-id is going to be the first one of the values (for a single column key) in the Map returned by getIdSnapshot(), it contains also the column name(s) associated to the PK as key(s):

objectId.getIdSnapshot().values()

This is how I did it:

EntityManager entityManager = getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(object);
transaction.commit();
long id = object.getId();
entityManager.close();

em.persist(abc);
em.refresh(abc);
return abc;

You could also use GenerationType.TABLE instead of IDENTITY which is only available after the insert.


This is how I did it. You can try

    public class ABCService {
    @Resource(name="ABCDao")
    ABCDao abcDao;

    public int addNewABC(ABC abc) {
         ABC.setId(0);
         return abcDao.insertABC(abc);
    }
}

@Entity
public class ABC implements Serializable {
     @Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)
     private int id;   
}

check that @GeneratedValue notation is there in your entity class.This tells JPA about your entity property auto-generated behavior