JPA - 在persist()之后返回自动生成的id

sur*_*a2k 101 java jpa

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

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

     // ...
}
Run Code Online (Sandbox Code Playgroud)

在我的DAO类中,我有一个调用persist()此实体的insert方法.我希望该方法返回新实体的生成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; // ???
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

    public int addNewABC(ABC abc) {
         return abcDao.insertABC(abc);
    }
}
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 169

只保证在刷新时生成ID.持久化实体只会使其"附加"到持久化上下文.因此,要么明确地刷新实体管理器:

em.persist(abc);
em.flush();
return abc.getId();
Run Code Online (Sandbox Code Playgroud)

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

@Override
public ABC addNewABC(ABC abc) {
    abcDao.insertABC(abc);
    return abc;
}
Run Code Online (Sandbox Code Playgroud)

  • 注意:这需要使用`@GeneratedValue`来激活id字段 - 无论需要什么 (10认同)
  • 是的,如果事务最终被回滚,则存在:对数据库的不必要的往返;如果持久化实体(或其他已刷新的实体)尚未处于有效状态,则可能存在异常.序列或uuid生成器更简单,更高效,并且没有这些问题,因为在将实体写入数据库之前生成并分配了ID. (3认同)
  • @JBNizet,您需要返回实例还是传递的引用仍然有效?我的意思是,“insertABC”会创建一个新对象吗?还是修改旧的? (2认同)

utk*_*tel 13

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

检查实体类中是否存在@GeneratedValue表示法.这告诉JPA您的实体属性自动生成的行为


Kor*_*gay 6

我就是这样做的:

EntityManager entityManager = getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(object);
transaction.commit();
long id = object.getId();
entityManager.close();
Run Code Online (Sandbox Code Playgroud)