Skip to content

Commit be4b942

Browse files
committed
Demonstrating use of composite ids in relational.
Original pull request #696
1 parent d888779 commit be4b942

File tree

14 files changed

+352
-0
lines changed

14 files changed

+352
-0
lines changed

jdbc/composite-ids/README.adoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
== Spring Data JDBC Composite Id
2+
3+
=== EmployeeTest
4+
5+
Demonstrates saving an entity with composite id.
6+
7+
Once by using a direct insert, via a custom `insert` method in the repository, backed by `JdbcAggregateTemplate.insert` and once by a custom id generating callback.
8+
See `CompositeConfiguration.idGeneration()`.

jdbc/composite-ids/pom.xml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<artifactId>spring-data-jdbc-composite-ids</artifactId>
7+
8+
<parent>
9+
<groupId>org.springframework.data.examples</groupId>
10+
<artifactId>spring-data-jdbc-examples</artifactId>
11+
<version>2.0.0.BUILD-SNAPSHOT</version>
12+
<relativePath>../pom.xml</relativePath>
13+
</parent>
14+
15+
<name>Spring Data JDBC - Examples using composite ids</name>
16+
<description>Sample project demonstrating Spring Data JDBCs support for custom ids</description>
17+
18+
<properties>
19+
<spring-data-bom.version>2025.1.0-M4</spring-data-bom.version>
20+
<spring-framework.version>7.0.0-M7</spring-framework.version>
21+
</properties>
22+
23+
<dependencies>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-web</artifactId>
27+
</dependency>
28+
</dependencies>
29+
30+
</project>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.jdbc.compositeid;
17+
18+
import org.springframework.context.annotation.Bean;
19+
import org.springframework.context.annotation.Configuration;
20+
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
21+
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
22+
import org.springframework.data.relational.core.mapping.event.BeforeConvertCallback;
23+
24+
import java.util.concurrent.atomic.AtomicLong;
25+
26+
27+
/**
28+
* Configuration for the demonstration of composite ids.
29+
*
30+
* Registers a {@link BeforeConvertCallback} for generating ids.
31+
*
32+
* @author Jens Schauder
33+
*/
34+
@Configuration
35+
@EnableJdbcRepositories
36+
public class CompositeConfiguration extends AbstractJdbcConfiguration {
37+
38+
@Bean
39+
BeforeConvertCallback<Employee> idGeneration() {
40+
return new BeforeConvertCallback<>() {
41+
AtomicLong counter = new AtomicLong();
42+
43+
@Override
44+
public Employee onBeforeConvert(Employee employee) {
45+
if (employee.id == null) {
46+
employee.id = new EmployeeId(Organization.RND, counter.addAndGet(1));
47+
}
48+
return employee;
49+
}
50+
};
51+
}
52+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.jdbc.compositeid;
17+
18+
import org.springframework.data.annotation.Id;
19+
import org.springframework.data.annotation.PersistenceCreator;
20+
21+
/**
22+
* A simple entity sporting a compostite id.
23+
*
24+
* @author Jens Schauder
25+
*/
26+
class Employee {
27+
28+
@Id
29+
EmployeeId id;
30+
31+
String name;
32+
33+
@PersistenceCreator
34+
Employee(EmployeeId id, String name) {
35+
36+
this.id = id;
37+
this.name = name;
38+
}
39+
40+
Employee(String name) {
41+
this.name = name;
42+
}
43+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.jdbc.compositeid;
17+
18+
/**
19+
* Composite id for {@link Employee} instances.
20+
*
21+
* @author Jens Schauder
22+
*/
23+
record EmployeeId(
24+
Organization organization,
25+
Long employeeNumber) {
26+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example.springdata.jdbc.compositeid;
18+
19+
import org.springframework.data.repository.Repository;
20+
21+
22+
/**
23+
* Repositories for {@link Employee} instances.
24+
*
25+
* @author Jens Schauder
26+
* @see InsertRepository
27+
* @see InsertRepositoryImpl
28+
*/
29+
interface EmployeeRepository extends Repository<Employee, EmployeeId>, InsertRepository<Employee> {
30+
Employee findById(EmployeeId id);
31+
32+
Employee save(Employee employee);
33+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.jdbc.compositeid;
17+
18+
19+
/**
20+
* Interface for repositories supporting an {@literal insert} operation, that always performs an insert on the database
21+
* and does not check the instance.
22+
*
23+
* @author Jens Schauder
24+
*/
25+
interface InsertRepository<E> {
26+
E insert(E employee);
27+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.jdbc.compositeid;
17+
18+
import org.springframework.beans.factory.annotation.Autowired;
19+
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
20+
21+
/**
22+
* Fragment implementing the {@literal insert} operation using a {@link JdbcAggregateTemplate}.
23+
*
24+
* @author Jens Schauder
25+
*/
26+
class InsertRepositoryImpl<E> implements InsertRepository<E> {
27+
28+
private JdbcAggregateTemplate template;
29+
30+
InsertRepositoryImpl(JdbcAggregateTemplate template) {
31+
this.template = template;
32+
}
33+
34+
@Override
35+
public E insert(E employee) {
36+
return template.insert(employee);
37+
}
38+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.jdbc.compositeid;
17+
18+
/**
19+
* Just an enum to be part of the composite id, to demonstrate that one may use various datatypes.
20+
*
21+
* @author Jens Schauder
22+
*/
23+
enum Organization {
24+
RND,
25+
SALES,
26+
MARKETING,
27+
PURCHASING
28+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@NonNullApi
2+
package example.springdata.jdbc.compositeid;
3+
4+
import org.springframework.lang.NonNullApi;

0 commit comments

Comments
 (0)