development

JPA-persist () 후 자동 생성 된 ID 반환

big-blog 2020. 8. 23. 09:49
반응형

JPA-persist () 후 자동 생성 된 ID 반환


JPA (EclipseLink)와 Spring을 사용하고 있습니다. 자동 생성 된 ID가있는 간단한 엔터티가 있다고 가정 해 보겠습니다.

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

     // ...
}

내 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; // ???
    }
}

차이가 나는 경우 DAO를 래핑하는 서비스 클래스도 있습니다.

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

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

ID는 플러시 시간에만 생성됩니다. 엔티티를 지속하면 지속성 컨텍스트에만 "연결"됩니다. 따라서 엔티티 관리자를 명시 적으로 비우십시오.

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

또는 ID가 아닌 항목 자체를 반환합니다. 트랜잭션이 종료되면 플러시가 발생하고 트랜잭션 외부의 엔티티 사용자는 엔티티에서 생성 된 ID를 볼 수 있습니다.

@Override
public ABC addNewABC(ABC abc) {
    abcDao.insertABC(abc);
    return 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


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();

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


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. You can try

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

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

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

참고URL : https://stackoverflow.com/questions/9732453/jpa-returning-an-auto-generated-id-after-persist

반응형