我正在将spring,h2和liquibase与hibernate一起使用,并且试图通过以本博客文章为例为我的实体创建自定义String id生成器,但出现错误:Caused by: org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String
Caused by: org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String
这是我的SequenceStyleGenerator代码:
public class CTCIDGenerator extends SequenceStyleGenerator { @Override public Serializable generate(SessionImplementor session, Object obj) { if (obj instanceof Identifiable) { Identifiable identifiable = (Identifiable) obj; Serializable id = identifiable.getId(); if (id != null) { return id; } } return "CTC"+super.generate(session, obj); } }
我的实体代码:
@Entity @Table(name = "contact") public class Contact implements Serializable, Identifiable<String> { private static final long serialVersionUID = 1L; @Id @GenericGenerator( name = "assigned-sequence", strategy = "net.atos.seirich.support.domain.idgenerator.CTCIDGenerator", parameters = @org.hibernate.annotations.Parameter( name = "sequence_name", value = "hibernate_sequence" ) ) @GeneratedValue(generator = "assigned-sequence", strategy = GenerationType.SEQUENCE) private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } }
和liquibase XML:
<?xml version="1.0" encoding="utf-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"> <property name="autoIncrement" value="true" dbms="mysql,h2,postgresql,oracle"/> <property name="floatType" value="float4" dbms="postgresql, h2"/> <property name="floatType" value="float" dbms="mysql, oracle"/> <changeSet id="20160513091901-1" author="jhipster"> <createTable tableName="contact"> <column name="id" type="longvarchar" autoIncrement="${autoIncrement}"> <constraints primaryKey="true" nullable="false"/> </column> </changeSet> </databaseChangeLog>
顺便说一句,有可能避免参数sequence_name,以便hibernate可以自行处理吗?
如果有人可以帮助我,谢谢!
问题是SequenceStyleGenerator期望返回一个数字值,而不是a String。
SequenceStyleGenerator
String
我已经尝试过解决此问题的方法,它就像一个魅力。因此,您需要像这样更改生成器:
public class StringSequenceIdentifier implements IdentifierGenerator, Configurable { private String sequenceCallSyntax; @Override public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException { final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class); final Dialect dialect = jdbcEnvironment.getDialect(); final String sequencePerEntitySuffix = ConfigurationHelper.getString(CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, params, DEF_SEQUENCE_SUFFIX); final String defaultSequenceName = ConfigurationHelper.getBoolean(CONFIG_PREFER_SEQUENCE_PER_ENTITY, params, false) ? params.getProperty(JPA_ENTITY_NAME) + sequencePerEntitySuffix : DEF_SEQUENCE_NAME; sequenceCallSyntax = dialect.getSequenceNextValString(ConfigurationHelper.getString(SEQUENCE_PARAM, params, defaultSequenceName)); } @Override public Serializable generate(SessionImplementor session, Object obj) { if (obj instanceof Identifiable) { Identifiable identifiable = (Identifiable) obj; Serializable id = identifiable.getId(); if (id != null) { return id; } } long seqValue = ((Number) Session.class.cast(session) .createSQLQuery(sequenceCallSyntax) .uniqueResult()).longValue(); return "CTC" + seqValue; } }
您的映射将变为:
@Entity(name = "Post") @Table(name = "post") public static class Post implements Identifiable<String> { @Id @GenericGenerator( name = "assigned-sequence", strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.StringSequenceIdentifier", parameters = @org.hibernate.annotations.Parameter(name = "sequence_name", value = "hibernate_sequence") ) @GeneratedValue(generator = "assigned-sequence", strategy = GenerationType.SEQUENCE) private String id; @Version private Integer version; public Post() { } public Post(String id) { this.id = id; } @Override public String getId() { return id; } }
现在,当您插入以下实体时:
doInJPA(entityManager -> { entityManager.persist(new Post()); entityManager.persist(new Post("ABC")); entityManager.persist(new Post()); entityManager.persist(new Post("DEF")); });
Hibernate生成正确的标识符:
Query:["select nextval ('hibernate_sequence')"], Params:[()] Query:["select nextval ('hibernate_sequence')"], Params:[()] Query:["insert into post (version, id) values (?, ?)"], Params:[(0, CTC1)] Query:["insert into post (version, id) values (?, ?)"], Params:[(0, ABC)] Query:["insert into post (version, id) values (?, ?)"], Params:[(0, CTC2)] Query:["insert into post (version, id) values (?, ?)"], Params:[(0, DEF)]
代码可在GitHub上获得。