当前位置: 首页 > 面试题库 >

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

颜嘉誉
2023-03-14
问题内容

标题中几乎说了出来。我有一堂课,看起来像这样:

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

  private String theId;

  @Id
  @Column(name = "FOO_ID")
  @GeneratedValue(strategy = Generathtml" target="_blank">ionType.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产生一个a
NUMBER。数据库显然对此感到满意,但是应用程序需要能够支持可能已插入到应用程序外部此列中的非数字ID。

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

使用Hibernate 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在持久性单元中未定义generator()。将此设置为警告,如下所示:

  1. 选择 窗口»首选项
  2. 展开 Java持久性»JPA»错误/警告
  3. 点击 查询和生成器
  4. 在持久性单元中未 将Set Generator定义 为:Warning
  5. 单击 确定 以应用更改并关闭对话框


 类似资料:
  • 问题内容: 我有一个类别hibernate模型: 其中有一个类型字符串字段。我也有一个Java枚举,它表示类别的类型: 我想用它代替字符串类型。SQL在varchar参数中接受两个不同的值:或。我希望Category模型类接受一个枚举变量- 每当hibernate要求它时,都以某种方式将其映射到字符串。 可能吗? 问题答案: 是的,有可能。它应该是:

  • 我有一个类别Hibernate模型: 它们具有类型字符串字段。另外,我还有一个Java枚举,它表示类别的一种类型:

  • 问题内容: 当前,我有一堆实现接口的Java类,这意味着它们都具有方法。这个想法是,每个类都有几个(例如<10)成员,并且每个类都通过方法映射到该类中的方法,如下所示: 你明白了。 这对我来说很好,但是现在我需要一个从键到函数的运行时可访问的映射。并非每个函数 实际上都 返回一个String(有些返回void),并且我需要动态地访问每个具有键的类中每个函数的返回类型(使用反射)。我已经有一位经理,

  • 我有下面的结构,我想用MapStruct映射这个。 下面是mapstruct为toDTO方法生成的实现 下面是mapstruct为toEntity方法生成的实现 我的问题是方法只在文本不为空时设置注释。但是方法不检查空文本或空文本。因此,如果我在DTO中获得,它将创建一个新的comment对象并将文本设置为null。如何避免这一点?有人能解释一下这种行为并建议我正确的做法吗?谢了!

  • 问题内容: 例如 输入:[‘A’,’Z’,’F’,’D’,…] 输出:[0,25,5,3,…] 在C语言中,我只是从’A’中减去char,但是我似乎无法在Java中做到这一点。 问题答案: 您也可以在Java中使用char进行简单的数学运算: 将输出0。

  • 嗨,我尝试将以下Source类映射到以下Destation类。我使用了以下映射以将字符串值映射到列表字符串。它没有正确映射。我需要知道如何使用Dozer将2个字符串值映射到一个目标字符串列表中。