Java JPA - 在 persist() 之后返回一个自动生成的 id
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9732453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA - Returning an auto generated id after persist()
提问by sura2k
I'm using JPA (EclipseLink) and Spring. Say I have a simple entity with an auto-generated ID:
我正在使用 JPA (EclipseLink) 和 Spring。假设我有一个带有自动生成 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.
在我的 DAO 类中,我有一个调用persist()
此实体的插入方法。我希望该方法返回为新实体生成的 ID,但是当我测试它时,它0
反而返回。
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:
我还有一个包装 DAO 的服务类,如果这有区别的话:
public class ABCService {
@Resource(name="ABCDao")
ABCDao abcDao;
public int addNewABC(ABC abc) {
return abcDao.insertABC(abc);
}
}
采纳答案by JB Nizet
The ID is only guaranteed to be generated at flush time. Persisting an entity only makes it "attached" to the persistence context. So, either flush the entity manager explicitely:
ID 只保证在刷新时生成。持久化一个实体只会使它“附加”到持久化上下文。因此,要么明确刷新实体管理器:
em.persist(abc);
em.flush();
return abc.getId();
or return the entity itself rather than its ID. When the transaction ends, the flush will happen, and users of the entity outside of the transaction will thus see the generated ID in the entity.
或返回实体本身而不是其 ID。当事务结束时,flush 就会发生,事务外实体的用户将因此在实体中看到生成的 ID。
@Override
public ABC addNewABC(ABC abc) {
abcDao.insertABC(abc);
return abc;
}
回答by Andrey
em.persist(abc);
em.refresh(abc);
return abc;
回答by James
You could also use GenerationType.TABLE instead of IDENTITY which is only available after the insert.
您还可以使用 GenerationType.TABLE 而不是 IDENTITY,后者仅在插入后可用。
回答by Koray Tugay
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();
回答by utkal patel
@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
检查您的实体类中是否存在 @GeneratedValue 表示法。这会告诉 JPA 您的实体属性自动生成的行为
回答by emecas
Another option compatible to 4.0:
另一个兼容 4.0 的选项:
Before committing the changes, you can recover the new CayenneDataObject
object(s) from the collection associated to the context, like this:
在提交更改之前,您可以CayenneDataObject
从与上下文关联的集合中恢复新对象,如下所示:
CayenneDataObject dataObjectsCollection = (CayenneDataObject)cayenneContext.newObjects();
then access the ObjectId
for each one in the collection, like:
然后访问ObjectId
集合中的每个,例如:
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):
最后,您可以在值下进行迭代,其中通常生成的 ID 将是由 返回的 Map 中的第一个值(对于单个列键)getIdSnapshot()
,它还包含与 PK 关联的列名作为密钥:
objectId.getIdSnapshot().values()
回答by Anh Khoa
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);
}
}