[java] 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;
}

엔티티 클래스에 @GeneratedValue 표기법이 있는지 확인하십시오. 이는 엔티티 속성 자동 생성 동작에 대해 JPA에 알려줍니다.


답변

이것이 내가 한 방법입니다.

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


답변

삽입 후에 만 ​​사용할 수있는 IDENTITY 대신 GenerationType.TABLE을 사용할 수도 있습니다.


답변

4.0과 호환되는 또 다른 옵션 :

변경 사항을 커밋하기 전에 CayenneDataObject다음과 같이 컨텍스트와 연결된 컬렉션에서 새 객체를 복구 할 수 있습니다 .

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

그런 다음 다음 ObjectId과 같이 컬렉션의 각 항목에 액세스합니다 .

ObjectId objectId = dataObject.getObjectId();

마지막으로 값 아래에서 반복 할 수 있습니다. 일반적으로 생성 된 ID는에서 반환 한 맵의 값 (단일 열 키의 경우) 중 첫 번째 값이됩니다 getIdSnapshot(). 여기에는 PK와 관련된 열 이름도 포함됩니다. 키로 :

objectId.getIdSnapshot().values()


답변

이것이 내가 한 방법입니다. 당신은 시도 할 수 있습니다

    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;