标题中几乎说了出来。我有一堂课,看起来像这样:
@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产生一个a NUMBER。数据库显然对此感到满意,但是应用程序需要能够支持可能已插入到应用程序外部此列中的非数字ID。
FOO_ID
VARCHAR2
SQ_FOO_ID
NUMBER
考虑上面的代码,我得到一个org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String。有什么办法可以做这种映射吗?
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()。将此设置为警告,如下所示:
seq_id
Warning