programing

최대 절전 모드에서 문자열을 DB 시퀀스에 매핑하는 방법

lovejava 2023. 8. 2. 08:36

최대 절전 모드에서 문자열을 DB 시퀀스에 매핑하는 방법

제목에 거의 다 나와 있습니다.다음과 같은 수업이 있습니다.

@Entity
@Table(name="FOO")
public class Foo {

  private String theId;

  @Id
  @Column(name = "FOO_ID")
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fooIdSeq")
  @SequenceGenerator(name = "fooIdSeq", sequenceName = "SQ_FOO_ID", allocationSize = 10)
  public String getTheId() { return theId; }

  public String setTheId(String theId) { this.theId = theId; }
}

Oracle 11g을 사용하여FOO_ID열은 a입니다.VARCHAR2하지만 순서는SQ_FOO_ID을 산출합니다.NUMBER데이터베이스는 이에 만족하는 것으로 보이지만, 응용프로그램은 응용프로그램 외부의 이 열에 삽입되었을 수 있는 숫자가 아닌 ID를 지원할 수 있어야 합니다.

위의 코드를 고려하면, 나는 다음과 같습니다.org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String이 매핑을 할 수 있는 방법이 있습니까?

최대 절전 모드 3.6 사용.

블로그 게시물에서 사용자 지정 IdentifierGenerator 클래스 구현:

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IdentifierGenerator;

public class StringKeyGenerator implements IdentifierGenerator {

    @Override
    public Serializable generate(SessionImplementor session, Object collection) throws HibernateException {
        Connection connection = session.connection();
        PreparedStatement ps = null;
        String result = "";

        try {
            // Oracle-specific code to query a sequence
            ps = connection.prepareStatement("SELECT TABLE_SEQ.nextval AS TABLE_PK FROM dual");
            ResultSet rs = ps.executeQuery();

            if (rs.next()) {
                int pk = rs.getInt("TABLE_PK");

                // Convert to a String
                result = Integer.toString(pk);
            }
        } catch (SQLException e) {
            throw new HibernateException("Unable to generate Primary Key");
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    throw new HibernateException("Unable to close prepared statement.");
                }
            }
        }

        return result;
    }
}

엔티티 PK에 다음과 같은 주석을 달 수 있습니다.

@Id
@GenericGenerator(name="seq_id", strategy="my.package.StringKeyGenerator")
@GeneratedValue(generator="seq_id")
@Column(name = "TABLE_PK", unique = true, nullable = false, length = 20)
public String getId() {
    return this.id;
}

Eclipse의 버그로 인해 제너레이터에 오류가 발생할 수 있습니다.seq_id)이(가) 지속성 단위에 정의되어 있지 않습니다.다음과 같이 경고로 설정합니다.

  1. 창 » 기본 설정 선택
  2. Java 지속성 » JPA » 오류/경고 확장
  3. 쿼리생성기 클릭
  4. Set Generator가 지속성 단위에서 다음과 같이 정의되지 않았습니다.Warning
  5. 확인을 클릭하여 변경사항을 적용하고 대화상자를 닫습니다.

다음은 또 다른 접근 방식입니다.

import java.io.Serializable;

import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IdentifierGeneratorHelper.BigDecimalHolder;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.SequenceGenerator;

public class StringSequenceGenerator extends SequenceGenerator {
    @Override
    public Serializable generate(SessionImplementor session, Object obj) {
        return super.generate( session, obj ).toString();
    }

    protected IntegralDataTypeHolder buildHolder() {
        return new BigDecimalHolder();
    }
}

시퀀스 매개 변수는 다음 예와 같이 id 속성에 지정해야 합니다.

@Id
@GenericGenerator(name = "STRING_SEQUENCE_GENERATOR", strategy = "mypackage.StringSequenceGenerator", parameters = { @Parameter(name = "sequence", value = "MY_SEQUENCE_NAME") })
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "STRING_SEQUENCE_GENERATOR")
@Column(name = "MY_ID")
public String getMyId() {
    return this.myId;
}

언급URL : https://stackoverflow.com/questions/12517421/how-to-map-a-string-to-db-sequence-in-hibernate