programing

jpa에서 객체를 저장하기 전에 id를 어떻게 알 수 있습니까?

padding 2023. 6. 22. 21:35
반응형

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

반응형