Skip to content

Commit bac15c1

Browse files
authored
sequence naming strategy (#17272)
1 parent ae3d307 commit bac15c1

File tree

8 files changed

+211
-0
lines changed

8 files changed

+211
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.baeldung.sequencenaming;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.GeneratedValue;
5+
import jakarta.persistence.GenerationType;
6+
import jakarta.persistence.Id;
7+
8+
@Entity
9+
public class Book {
10+
11+
@Id
12+
@GeneratedValue(strategy = GenerationType.SEQUENCE)
13+
private Long id;
14+
private String title;
15+
16+
public Long getId() {
17+
return id;
18+
}
19+
20+
public void setId(Long id) {
21+
this.id = id;
22+
}
23+
24+
public String getTitle() {
25+
return title;
26+
}
27+
28+
public void setTitle(String title) {
29+
this.title = title;
30+
}
31+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.baeldung.sequencenaming;
2+
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
5+
public interface BookRepository extends JpaRepository<Book, Long> {
6+
7+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.baeldung.sequencenaming;
2+
3+
import static org.hibernate.id.enhanced.TableGenerator.DEF_TABLE;
4+
5+
import java.util.Map;
6+
7+
import org.hibernate.boot.model.naming.Identifier;
8+
import org.hibernate.boot.model.relational.QualifiedName;
9+
import org.hibernate.boot.model.relational.QualifiedNameParser;
10+
import org.hibernate.boot.model.relational.QualifiedSequenceName;
11+
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
12+
import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy;
13+
import org.hibernate.service.ServiceRegistry;
14+
15+
public class CustomSequenceNamingStrategy implements ImplicitDatabaseObjectNamingStrategy {
16+
17+
@Override
18+
public QualifiedName determineSequenceName(Identifier catalogName, Identifier schemaName, Map<?, ?> map, ServiceRegistry serviceRegistry) {
19+
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class);
20+
final String seqName = ((String) map.get("jpa_entity_name")).concat("_custom_seq");
21+
return new QualifiedSequenceName(
22+
catalogName,
23+
schemaName,
24+
jdbcEnvironment.getIdentifierHelper().toIdentifier(seqName));
25+
}
26+
27+
@Override
28+
public QualifiedName determineTableName(Identifier catalogName, Identifier schemaName, Map<?, ?> map, ServiceRegistry serviceRegistry) {
29+
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class);
30+
31+
return new QualifiedNameParser.NameParts(
32+
catalogName,
33+
schemaName,
34+
jdbcEnvironment.getIdentifierHelper().toIdentifier(DEF_TABLE));
35+
}
36+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.baeldung.sequencenaming;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.GeneratedValue;
5+
import jakarta.persistence.GenerationType;
6+
import jakarta.persistence.Id;
7+
import jakarta.persistence.SequenceGenerator;
8+
import jakarta.persistence.Table;
9+
10+
@Entity
11+
//@Table(name = "my_person_table")
12+
public class Person {
13+
14+
@Id
15+
@GeneratedValue(strategy = GenerationType.SEQUENCE)
16+
// @Id
17+
// @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "person_custom_seq")
18+
// @SequenceGenerator(name = "person_custom_seq", sequenceName = "person_custom_seq", allocationSize = 10)
19+
private Long id;
20+
private String name;
21+
22+
public Long getId() {
23+
return id;
24+
}
25+
26+
public void setId(Long id) {
27+
this.id = id;
28+
}
29+
30+
public String getName() {
31+
return name;
32+
}
33+
34+
public void setName(String name) {
35+
this.name = name;
36+
}
37+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.baeldung.sequencenaming;
2+
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
5+
public interface PersonRepository extends JpaRepository<Person, Long> {
6+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.baeldung.sequencenaming;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class SequenceNamingApp {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(SequenceNamingApp.class, args);
11+
}
12+
13+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Database Configuration
2+
spring.datasource.url=jdbc:h2:mem:testdb
3+
spring.datasource.username=sa
4+
spring.datasource.password=password
5+
spring.datasource.driver-class-name=org.h2.Driver
6+
7+
# Hibernate Configuration
8+
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
9+
spring.jpa.hibernate.ddl-auto=update
10+
spring.jpa.show-sql=true
11+
spring.jpa.properties.hibernate.format_sql=true
12+
spring.jpa.properties.hibernate.use_sql_comments=true
13+
14+
# Naming Strategy Configuration
15+
spring.jpa.properties.hibernate.id.db_structure_naming_strategy=standard
16+
#spring.jpa.properties.hibernate.id.db_structure_naming_strategy=legacy
17+
#spring.jpa.properties.hibernate.id.db_structure_naming_strategy=single
18+
#spring.jpa.properties.hibernate.id.db_structure_naming_strategy=com.baeldung.sequencenaming.CustomSequenceNamingStrategy
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.baeldung.sequencenaming;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertThat;
5+
import static org.junit.Assert.assertTrue;
6+
7+
import java.sql.Connection;
8+
import java.util.List;
9+
10+
import javax.sql.DataSource;
11+
12+
import org.junit.Ignore;
13+
import org.junit.jupiter.api.BeforeEach;
14+
import org.junit.jupiter.api.Test;
15+
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
17+
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
18+
import org.springframework.boot.test.context.SpringBootTest;
19+
20+
@SpringBootTest(properties = "spring.config.location=classpath:application-test.properties")
21+
public class PersonRepositoryIntegrationTest {
22+
23+
@Autowired
24+
private PersonRepository personRepository;
25+
26+
@Autowired
27+
private BookRepository bookRepository;
28+
29+
@Test
30+
@Ignore
31+
void givenNamingStrategy_whenSavingPerson_thenSequenceIsCreatedWithSpecifiedNamingStrategy() {
32+
// Change the naming strategy in properties file to see the differences.
33+
34+
Person person = new Person();
35+
person.setName("John Doe");
36+
personRepository.save(person);
37+
38+
List<Person> personList = personRepository.findAll();
39+
40+
assertTrue(personList.size() > 0);
41+
}
42+
43+
@Test
44+
@Ignore
45+
void givenSingleNamingStrategy_whenSavingPersonAndBook_thenUsesSameSequenceForBoth() {
46+
// Change the naming strategy in properties file to see the differences.
47+
48+
Person person = new Person();
49+
person.setName("John Doe");
50+
personRepository.save(person);
51+
52+
Book book = new Book();
53+
book.setTitle("Baeldung");
54+
bookRepository.save(book);
55+
56+
List<Person> personList = personRepository.findAll();
57+
List<Book> bookList = bookRepository.findAll();
58+
59+
assertEquals((long)1,(long) personList.get(0).getId());
60+
assertEquals((long)2, (long)bookList.get(0).getId());
61+
}
62+
63+
}

0 commit comments

Comments
 (0)