gpt4 book ai didi

java - 使用多个@GenericGenerator?

转载 作者:行者123 更新时间:2023-11-30 06:25:34 25 4
gpt4 key购买 nike

我在 Spring Boot 项目 (Hibernate 5) 中尝试了 Hibernate 的 @GenericGenerator。制作了这样的测试实体:

@Entity
public class BatchTest implements Serializable {
private static final long serialVersionUID = 3012542467060581674L;

@Id
@GeneratedValue(generator = "batchTestIdGenerator")
@GenericGenerator(
name = "batchTestIdGenerator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@org.hibernate.annotations.Parameter(name = "increment_size",value = "1000")
}
)
private long id;

@Lob
@Column(nullable = false)
private String someVal;
...

使用这个生成器,我可以使用 JPA 快速插入实体(我有一个 Spring 存储库,由 @Service 提供服务),这很酷,但是序列实际上是如何存储的?我的数据库当前是一个 SQL Server 2016 实例,在架构中,我可以看到我有一个 dbo.hibernate_sequence : enter image description here

如果我使用不同的生成器创建第二个实体,我会在启动过程中遇到异常:

@Id
@GeneratedValue(generator = "batchTestIdGenerator2", strategy = GenerationType.SEQUENCE)
@GenericGenerator(
name = "batchTestIdGenerator2",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@org.hibernate.annotations.Parameter(name = "increment_size",value = "500")
}
)
private long id;

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Multiple references to database sequence [hibernate_sequence] were encountered attempting toset conflicting values for 'increment size'. Found [500] and [1000]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]

我可以定义不同的序列吗?看起来它尝试对两个序列使用相同的 dbo.hibernate_sequence (id 没有在数据库中创建新的 dbo 序列)并且只是忽略名称。如果可以定义N个序列,我该怎么做?

编辑:我尝试手动创建序列(匹配名称),但仍然遇到相同的错误。

最佳答案

Hibernate 允许您创建自己的序列生成器,它允许您使用 Hibernate IdentifierGenerator 定义格式和表格。请尝试以下方法。

通过实现 IdentifierGenerator 创建一个 SequenceGenerator 类,使用 org.hibernate.id.Configurable 接口(interface)使您的 Generator 可配置 -它将接受来自实体类的参数-

自定义标识符生成器如下所示:

public class StringSequenceIdentifier 
implements IdentifierGenerator, Configurable {

public static final String SEQUENCE_PREFIX = "sequence_prefix";

private String sequencePrefix;

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();

sequencePrefix = ConfigurationHelper.getString(
SEQUENCE_PREFIX,
params,
"SEQ_");

final String sequencePerEntitySuffix = ConfigurationHelper.getString(
SequenceStyleGenerator.CONFIG_SEQUENCE_PER_ENTITY_SUFFIX,
params,
SequenceStyleGenerator.DEF_SEQUENCE_SUFFIX);

final String defaultSequenceName = ConfigurationHelper.getBoolean(
SequenceStyleGenerator.CONFIG_PREFER_SEQUENCE_PER_ENTITY,
params,
false)
? params.getProperty(JPA_ENTITY_NAME) + sequencePerEntitySuffix
: SequenceStyleGenerator.DEF_SEQUENCE_NAME;

sequenceCallSyntax = dialect.getSequenceNextValString(
ConfigurationHelper.getString(
SequenceStyleGenerator.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 sequencePrefix + String.format("%011d%s", 0 ,seqValue);
}
}

实体会像

@Entity(name = "Post") @Table(name = "post")
public 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"),
@org.hibernate.annotations.Parameter(
name = "sequence_prefix", value = "CTC_"),
}
)
@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;
}
}

详细说明请引用以下链接。 https://vladmihalcea.com/how-to-implement-a-custom-string-based-sequence-identifier-generator-with-hibernate/

关于java - 使用多个@GenericGenerator?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47280364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com