java - 如何在 Hibernate 中将字符串映射到数据库序列

标签 java oracle hibernate

在标题中几乎已经说明了这一点。我有一个看起来像这样的类:

@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 列是一个 VARCHAR2,但序列 SQ_FOO_ID 产生一个 NUMBER。数据库显然对此很满意,但应用程序需要能够支持可能已在应用程序外部插入到此列中的非数字 ID。

考虑到上面的代码,我得到一个 org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String。有什么办法可以做这个映射吗?

使用 Hibernate 3.6。

最佳答案

实现一个自定义的IdentifierGenerator类;来自blog post :

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. Generator is not defined in the persistence unit 设置为:Warning
  5. 点击确定应用更改并关闭对话框

关于java - 如何在 Hibernate 中将字符串映射到数据库序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12517421/

相关文章:

java - 关于 Web 应用程序环境中的 Java Executor 框架

sql - 为 Sql Developer 导入设置默认列值

database - Oracle中如何查看表的哪一列被授予了用户

hibernate - 如何在 gradle 中启用 Hibernate Bytecode 增强

java - 对 transient 集合字段的 Hibernate 注释

hibernate - hibernate 映射失败 : An association from the table X refers to an unmapped class Y

java - 在 JAVA 中从 main 访问函数内的数组或变量

Java在方法之间传递参数

javax.servlet.ServletException : java. lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/Cell

Oracle 物化 View