JPA-在持久化()之后返回自动生成的 id

我使用的是 JPA (EclipseLink)和 Spring。假设我有一个自动生成 ID 的简单实体:

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


// ...
}

在我的 DAO 类中,我有一个 insert 方法,它对这个实体调用 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; // ???
}
}

我还有一个包装 DAO 的服务类,如果这有什么不同的话:

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


public int addNewABC(ABC abc) {
return abcDao.insertABC(abc);
}
}
155944 次浏览

只保证在刷新时生成 ID。持久化实体只会使其“附加”到持久化上下文。因此,要么显式刷新实体管理器:

em.persist(abc);
em.flush();
return abc.getId();

或者返回实体本身,而不是它的 ID。当事务结束时,刷新将发生,因此事务外实体的用户将看到实体中生成的 ID。

@Override
public ABC addNewABC(ABC abc) {
abcDao.insertABC(abc);
return abc;
}
em.persist(abc);
em.refresh(abc);
return abc;

您还可以使用 GenerationType.TABLE 来代替仅在插入之后才可用的 IDENTITY。

我是这么做的:

EntityManager entityManager = getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(object);
transaction.commit();
long id = object.getId();
entityManager.close();
@Entity
public class ABC implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
}

检查实体类中是否有@GeneratedValue 符号,这将告诉 JPA 实体属性自动生成的行为

另一个兼容4.0的选项:

在提交更改之前,可以从与上下文关联的集合中恢复新的 CayenneDataObject对象,如下所示:

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

然后访问集合中每一个的 ObjectId,如:

ObjectId objectId = dataObject.getObjectId();

最后,您可以在值下迭代,通常生成的 -id 将是 getIdSnapshot()返回的 Map 中的第一个值(对于单个列键) ,它还包含与 PK 关联的列名作为键:

objectId.getIdSnapshot().values()

我就是这么做的,你可以试试

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


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