jpa에서 객체를 저장하기 전에 id를 어떻게 알 수 있습니까?
저는 새로운 물건을 가지고 있습니다.저장하기 전에 id를 알고 싶습니다.가능합니까?아니면 이것을 위한 다른 방법이 있습니까?저는 jpa를 oracle을 데이터베이스로 사용하고 있습니다.
@Id
@Basic(optional = false)
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "woTypeSeq")
private Long id;
엔티티에 코드 필드가 있습니다.사용자가 다음 값을 입력하지 않은 경우code
필드, 엔티티 ID로 코드를 설정합니다.엔티티를 유지하면 당연히 id를 얻고 코드 값을 id로 설정할 수 있지만, 이것은 추가 쿼리 데이터베이스입니다.
저는 그런 일을 하고 싶습니다.
if(entity.getCode()==null) {
entity.setCode(entity.getId);
jpaDao.saveOrUpdate(entity);
}
@GeneratedValue 유형 ID를 사용하면 해당 값을 실제로 쓰기 전에 미리 알 수 없습니다.그러나 Bean을 유지하면 ID 필드가 해당 Bean 인스턴스에 채워지므로 추가 쿼리를 수행하지 않고도 Bean을 얻을 수 있습니다.즉, 다음과 같습니다.
MyEntiry myEnt = new MyEntity(); //the id field is null now
entityManager.persist(myEnt);//the id field is populated in myEnt now
Long id = myEnt.getId();
또한, 당신의 방식에 따라.EntityManager
이 구성되어 있으므로 해당 ID를 얻기 전에 먼저 트랜잭션을 커밋해야 할 수도 있습니다.
주석에 따라 업데이트
엔티티를 저장 및/또는 업데이트하기 전에 엔티티를 가로채서 작업을 수행하려면 JPA LifeCycle Listeners(JPA 버전 2를 사용하는 경우): 수신기 및 콜백을 사용한 JPA 수명 주기 이벤트 처리를 사용할 수 있습니다.
기본적으로 당신은 만들 수 있습니다.validate()
당신의 빈에 있는 방법, 그것에 주석을 달아라.@PrePersist
그리고.@PreUpdate
그리고 그 안에서 검증을 수행합니다(코드가 비어 있는 경우 ID 값으로 설정).
두 번째 주석별 업데이트
네, 솔직히 방금 생각한 것은 id가 자동 생성되면 사전 지속 이벤트 이후에 채워질 수 있기 때문입니다. 따라서 사전 지속 코드가 실행될 때 id가 무엇인지 알 수 없습니다(이 예에서는 id에 링크하는 것이 자동 생성되지 않고 수동으로 설정됨).이 경우에 수행할 수 있는 작업은 엔티티에 부울 필드를 추가하는 것입니다.@Transient
지속되지 않도록) 호출됩니다.isCodeEmpty
(구체적으로 초기화되지 않은 경우 기본적으로 false임).그럼 당신의@PrePersist
코드 필드의 값이 비어 있는지 확인하고, 비어 있으면 부울을 true로 설정합니다.그런 다음 당신은 당신의setId(...)
메서드는 (id 필드를 설정할 때 제외됨) 이 부울을 확인하고, true이면 코드 필드의 값을 id 필드의 값으로 설정합니다.
public class YourEntity {
@Transient
private boolean isCodeEmpty;
public void setId(Whatever id) {
this.id = id;
if(isCodeEmpty) {
this.code = id;
//if necessary:
//this.isCodeEmpty = false;
}
}
@PrePersist
public void validate() {
if(code == null || code.isEmpty()) {
isCodeEmpty = true;
}
}
}
이것에 대해 오랜 연구 끝에 마침내 해결책을 찾았습니다.
실제로 jpa에서 시퀀스 생성기를 사용하는 경우 데이터베이스 시퀀스에 의해 다음 ID가 할당되기 때문에 데이터베이스에 저장하기 전에 엔티티 ID를 가져올 수 없습니다.
사용자 지정 생성기를 사용하는 경우 id를 얻는 한 가지 방법이 있습니다. 저장하기 전에 id를 얻을 수 있습니다.간단한 구현 방법은 다음과 같습니다.
public class CustomGenerator extends IdentityGenerator implements Configurable {
private IdentifierGenerator defaultGenerator;
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
Long idValue = (Long)defaultGenerator.generate(session, object);
//idValue will be assigned your entity id
return idValue;
}
@Override
public void configure(Type type, Properties params, Dialect d) throws MappingException {
DefaultIdentifierGeneratorFactory dd = new DefaultIdentifierGeneratorFactory();
dd.setDialect(d);
defaultGenerator = dd.createIdentifierGenerator("sequence", type, params);
}
}
ID 필드에 CustomGenerator 사용:
@Id
@Basic(optional = false)
@Column(name = "ID", nullable = false)
@GenericGenerator(name = "seq_id", strategy = "com.yoncabt.abys.core.listener.CustomGenerator", parameters = { @Parameter(name = "sequence", value = "II_FIRM_DOC_PRM_SEQ") })
@GeneratedValue(generator = "seq_id")
private Long id;
저에게 맞는 솔루션은 다음과 같습니다.
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "my_seq" )
@SequenceGenerator( name = "my_seq", sequenceName = "my_seq" )
@Access( AccessType.PROPERTY )
private Long id;
@Column( name = "CODE", nullable = false, updatable = false )
private Long code;
public void setId(Long id) {
this.id = id;
if (code == null) {
code = id;
}
}
은 중한부다배것는다입니치하음을 놓는 입니다.@javax.persistence.Access( AccessType.PROPERTY )
주석 - 최대 절전 모드에서 getter와 setter를 사용하여 id 필드에 액세스하도록 합니다.이 기능이 없으면 @Id 주석이 필드 게터가 아닌 필드에 직접 배치될 때 최대 절전 모드는 필드 기반 액세스 전략을 사용합니다(게터 및 세터는 사용되지 않음).링크: https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/access.htmlhiber
다음 단계를 수행하기만 하면 트랜잭션을 완료하기 전에 ID를 얻을 수 있습니다.
합니다. 즉, " 엔번단계같사주다니첫 째 수 수 추 엔 합 가 를 기 신 티 터 하 여 서 용 에 준 터 을 티 석 은 다 음 는 과 ation ▁listener ▁an@EntityListeners
.
@Id
@Basic(optional = false)
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "woTypeSeq")
@EntityListeners(SomeLinstener.class)
private Long id;
두 번째 단계
public class SomeLinstener{
@PostPersist
public void userPostPersist(YourEntity obj) {
try {
obj.getId();
}catch(Exception e) {
}
}
이렇게 하면 생성기에서 생성한 ID를 사용할 수 있으며, 필요한 모든 곳에서 한 번의 트랜잭션으로 재사용할 수 있습니다.
이것이 다른 사람에게 도움이 되기를 바랍니다.
언급URL : https://stackoverflow.com/questions/12742826/how-do-i-know-the-id-before-saving-an-object-in-jpa
'programing' 카테고리의 다른 글
MongoDB 특정 배열 값 바꾸기 (0) | 2023.06.22 |
---|---|
UI 이미지를 파일에 저장하려면 어떻게 해야 합니까? (0) | 2023.06.22 |
윈도우즈가 부팅될 때 오라클 데이터베이스가 시작되지 않도록 방지하는 방법은 무엇입니까? (0) | 2023.06.22 |
SSL_connect에서 반환된 =1 errno=0 상태=SSLv3 읽기 서버 인증서 B: 인증서 확인 실패 (0) | 2023.06.22 |
Android의 Test와 동일한 기능을 가진 iOS에서 메시지 표시 (0) | 2023.06.22 |