Skip to content

Commit d88975a

Browse files
committed
Add support for @IdGeneratorType
Fixes #17
1 parent fd98b3a commit d88975a

File tree

6 files changed

+75
-54
lines changed

6 files changed

+75
-54
lines changed

README.md

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,7 @@ You can use this sequence generator like this
3838

3939
```java
4040
@Id
41-
@GenericGenerator(
42-
name = "some_column_name_id_generator",
43-
strategy = "com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator",
44-
parameters = {
45-
@Parameter(name = "sequence", value = "SOME_SEQUENCE_NAME"),
46-
@Parameter(name = "fetch_size", value = "SOME_FETCH_SIZE_VALUE")
47-
})
48-
@GeneratedValue(generator = "some_column_name_id_generator")
49-
@Column(name = "SOME_COLUMN_NAME")
41+
@BatchSequence(name = "SOME_SEQUENCE_NAME", fetch_size = SOME_FETCH_SIZE_VALUE)
5042
private Long someColumnName;
5143
```
5244

@@ -56,11 +48,7 @@ You need to configure the following things
5648
<dt>SOME_SEQUENCE_NAME</dt>
5749
<dd>the SQL name of the sequence from which the values should be fetched</dd>
5850
<dt>SOME_FETCH_SIZE_VALUE</dt>
59-
<dd>integer, how many values should be fetched at once, this should be equal to the <code>CACHE</code> value of the sequence</dd>
60-
<dt>SOME_COLUMN_NAME</dt>
61-
<dd>the SQL name of the column for which the value should be generated</dd>
62-
<dt>some_column_name_id_generator</dt>
63-
<dd>unique if of the generator</dd>
51+
<dd>integer, how many values should be fetched at once, this should be equal to the <code>CACHE</code> value of the sequence, optional, default value is 10</dd>
6452
</dl>
6553

6654

pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@
220220
<dependency>
221221
<groupId>org.springframework</groupId>
222222
<artifactId>spring-framework-bom</artifactId>
223-
<version>6.1.7</version>
223+
<version>6.1.10</version>
224224
<type>pom</type>
225225
<scope>import</scope>
226226
</dependency>
@@ -280,7 +280,7 @@
280280
<dependency>
281281
<groupId>org.hsqldb</groupId>
282282
<artifactId>hsqldb</artifactId>
283-
<version>2.7.2</version>
283+
<version>2.7.3</version>
284284
<scope>test</scope>
285285
</dependency>
286286
<dependency>
@@ -304,7 +304,7 @@
304304
<dependency>
305305
<groupId>org.firebirdsql.jdbc</groupId>
306306
<artifactId>jaybird</artifactId>
307-
<version>5.0.4.java11</version>
307+
<version>5.0.5.java11</version>
308308
<scope>test</scope>
309309
</dependency>
310310
<dependency>
@@ -411,7 +411,7 @@
411411
<properties>
412412
<project.reporting.outputEncoding>utf-8</project.reporting.outputEncoding>
413413
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
414-
<hibernate.version>6.5.1.Final</hibernate.version>
414+
<hibernate.version>6.5.2.Final</hibernate.version>
415415
<project.build.outputTimestamp>2024-01-26T13:19:42Z</project.build.outputTimestamp>
416416
</properties>
417417

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.github.marschall.hibernate.batchsequencegenerator;
2+
3+
import static java.lang.annotation.ElementType.FIELD;
4+
import static java.lang.annotation.ElementType.METHOD;
5+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
6+
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.Target;
9+
10+
import org.hibernate.annotations.IdGeneratorType;
11+
12+
/**
13+
* Meta annotation to use {@link BatchSequenceGenerator} as an identifier generator.
14+
*/
15+
@IdGeneratorType(BatchSequenceGenerator.class)
16+
@Retention(RUNTIME)
17+
@Target({ FIELD, METHOD })
18+
public @interface BatchSequence {
19+
20+
/**
21+
* Returns the name of the sequence to use.
22+
*
23+
* @return the name of the sequence to use
24+
*/
25+
String name();
26+
27+
/**
28+
* Returns how many sequence values to fetch at once.
29+
*
30+
* @return how many sequence values to fetch at once, must be positive
31+
*/
32+
int fetchSize() default BatchSequenceGenerator.DEFAULT_FETCH_SIZE;
33+
34+
}

src/main/java/com/github/marschall/hibernate/batchsequencegenerator/BatchSequenceGenerator.java

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.hibernate.HibernateException;
1919
import org.hibernate.MappingException;
2020
import org.hibernate.boot.model.relational.Database;
21+
import org.hibernate.boot.model.relational.ExportableProducer;
2122
import org.hibernate.boot.model.relational.QualifiedNameParser;
2223
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
2324
import org.hibernate.dialect.Dialect;
@@ -27,10 +28,7 @@
2728
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
2829
import org.hibernate.id.IdentifierGenerationException;
2930
import org.hibernate.id.IdentifierGenerator;
30-
import org.hibernate.id.PersistentIdentifierGenerator;
3131
import org.hibernate.id.enhanced.DatabaseStructure;
32-
import org.hibernate.id.enhanced.NoopOptimizer;
33-
import org.hibernate.id.enhanced.Optimizer;
3432
import org.hibernate.id.enhanced.SequenceStructure;
3533
import org.hibernate.internal.util.config.ConfigurationHelper;
3634
import org.hibernate.service.ServiceRegistry;
@@ -40,15 +38,12 @@
4038
* A sequence generator that uses a recursive query to fetch multiple
4139
* values from a sequence in a single database access.
4240
*
43-
* <h2>Parameters</h2>
44-
* The following configuration parameters are supported:
45-
* <dl>
46-
* <dt>{@value #SEQUENCE_PARAM}</dt>
47-
* <dd><strong>mandatory</strong>, name of the sequence to use</dd>
48-
* <dt>{@value #FETCH_SIZE_PARAM}</dt>
49-
* <dd>optional, how many sequence numbers should be fetched at a time,
50-
* default is {@value #DEFAULT_FETCH_SIZE}</dd>
51-
* </dl>
41+
* <h2>Configuration</h2>
42+
* <pre><code>
43+
* &commat;Id
44+
* &commat;BatchSequence(name = "SOME_SEQUENCE_NAME", fetch_size = SOME_FETCH_SIZE_VALUE)
45+
* private Long someColumnName;
46+
* </code></pre>
5247
*
5348
* <h2>SQL</h2>
5449
* Per default the generated SELECT will look something like this
@@ -136,16 +131,22 @@
136131
* In theory any RDBMS that supports {@code WITH RECURSIVE} and
137132
* sequences is supported.
138133
*/
139-
public class BatchSequenceGenerator implements BulkInsertionCapableIdentifierGenerator, PersistentIdentifierGenerator {
134+
public final class BatchSequenceGenerator implements BulkInsertionCapableIdentifierGenerator, IdentifierGenerator, ExportableProducer {
140135

141136
/**
142137
* Indicates the name of the sequence to use, mandatory.
138+
*
139+
* @deprecated use {@link BatchSequence}
143140
*/
141+
@Deprecated
144142
public static final String SEQUENCE_PARAM = "sequence";
145143

146144
/**
147145
* Indicates how many sequence values to fetch at once. The default value is {@link #DEFAULT_FETCH_SIZE}.
146+
*
147+
* @deprecated use {@link BatchSequence}
148148
*/
149+
@Deprecated
149150
public static final String FETCH_SIZE_PARAM = "fetch_size";
150151

151152
/**
@@ -154,27 +155,40 @@ public class BatchSequenceGenerator implements BulkInsertionCapableIdentifierGen
154155
public static final int DEFAULT_FETCH_SIZE = 10;
155156

156157
private final Lock lock = new ReentrantLock();
158+
private final BatchSequence annotation;
157159

158160
private String select;
159161
private int fetchSize;
160162
private IdentifierPool identifierPool;
161163
private IdentifierExtractor identifierExtractor;
162164
private DatabaseStructure databaseStructure;
163-
private NoopOptimizer optimizer;
165+
166+
public BatchSequenceGenerator(BatchSequence annotation) {
167+
this.annotation = annotation;
168+
}
169+
170+
public BatchSequenceGenerator() {
171+
this.annotation = null;
172+
}
164173

165174
@Override
166175
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) {
167176

168177
JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class);
169178
Dialect dialect = jdbcEnvironment.getDialect();
170-
String sequenceName = determineSequenceName(params);
171-
this.fetchSize = determineFetchSize(params);
179+
String sequenceName;
180+
if (this.annotation != null) {
181+
sequenceName = this.annotation.name();
182+
this.fetchSize = this.annotation.fetchSize();
183+
} else {
184+
sequenceName = determineSequenceName(params);
185+
this.fetchSize = determineFetchSize(params);
186+
}
172187

173188
this.select = buildSelect(sequenceName, dialect);
174189
Class<?> returnedClass = type.getReturnedClass();
175190
this.identifierExtractor = IdentifierExtractor.getIdentifierExtractor(returnedClass);
176191
this.identifierPool = IdentifierPool.empty();
177-
this.optimizer = new NoopOptimizer(returnedClass, 1);
178192

179193
this.databaseStructure = this.buildDatabaseStructure(type, sequenceName, jdbcEnvironment, params);
180194
}
@@ -281,11 +295,6 @@ public Serializable generate(SharedSessionContractImplementor session, Object ob
281295
}
282296
}
283297

284-
@Override
285-
public Optimizer getOptimizer() {
286-
return this.optimizer;
287-
}
288-
289298
private String getSequenceName() {
290299
return this.databaseStructure.getPhysicalName().getObjectName().getCanonicalName();
291300
}

src/test/java/com/github/marschall/hibernate/batchsequencegenerator/configurations/HibernateConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ public LocalContainerEntityManagerFactoryBean entityManager() {
2929
bean.setPersistenceUnitName(this.environment.getProperty(PERSISTENCE_UNIT_NAME));
3030
bean.setJpaDialect(this.jpaDialect());
3131
bean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
32+
// Map<String, Object> jpaProperties = Map.of(AvailableSettings.PHYSICAL_NAMING_STRATEGY, new CamelCaseToUnderscoresNamingStrategy());
33+
// bean.setJpaPropertyMap(jpaProperties);
3234
bean.setDataSource(this.dataSource);
3335
return bean;
3436
}

src/test/java/com/github/marschall/hibernate/batchsequencegenerator/entities/ParentEntity.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
package com.github.marschall.hibernate.batchsequencegenerator.entities;
22

3-
import static com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator.FETCH_SIZE_PARAM;
4-
import static com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator.SEQUENCE_PARAM;
5-
63
import java.util.HashSet;
74
import java.util.Set;
85

9-
import org.hibernate.annotations.GenericGenerator;
10-
import org.hibernate.annotations.Parameter;
6+
import com.github.marschall.hibernate.batchsequencegenerator.BatchSequence;
117

128
import jakarta.persistence.Column;
139
import jakarta.persistence.Entity;
14-
import jakarta.persistence.GeneratedValue;
1510
import jakarta.persistence.Id;
1611
import jakarta.persistence.JoinColumn;
1712
import jakarta.persistence.OneToMany;
@@ -20,14 +15,7 @@
2015
public class ParentEntity {
2116

2217
@Id
23-
@GenericGenerator(
24-
name = "parent_id_generator",
25-
strategy = "com.github.marschall.hibernate.batchsequencegenerator.BatchSequenceGenerator",
26-
parameters = {
27-
@Parameter(name = SEQUENCE_PARAM, value = "SEQ_PARENT_ID"),
28-
@Parameter(name = FETCH_SIZE_PARAM, value = "50")
29-
})
30-
@GeneratedValue(generator = "parent_id_generator")
18+
@BatchSequence(name = "SEQ_PARENT_ID", fetchSize = 50)
3119
@Column(name = "PARENT_ID")
3220
private Long parentId;
3321

0 commit comments

Comments
 (0)