Skip to content

Commit 54914e8

Browse files
Merge pull request #176 from xdev-software/develop
v2.3.0
2 parents 6e52e2d + f2cec3d commit 54914e8

File tree

46 files changed

+925
-111
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+925
-111
lines changed

.github/workflows/broken-links.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
- name: Link Checker
2020
id: lychee
21-
uses: lycheeverse/lychee-action@v1
21+
uses: lycheeverse/lychee-action@v2
2222

2323
- name: Find already existing issue
2424
id: find-issue

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 2.3.0
2+
3+
* Add support for shuting down the storage during application shutdown
4+
* By default only enabled when Spring DevTools are active
5+
* This should fix "StorageExceptionInitialization: Active storage for ... already exists" errors during DevTools restart
6+
* Added [Jakarta Bean Validation Constraints](https://jakarta.ee/learn/docs/jakartaee-tutorial/current/beanvalidation/bean-validation/bean-validation.html#_using_jakarta_bean_validation_constraints) with Hibernate validator for entities.
7+
18
# 2.2.2
29

310
* Fixed NPE in EclipseSerializerRegisteringCopier

docs/antora.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
name: ROOT
22
title: Spring-Data-Eclipse-Store
33
version: master
4-
display_version: '2.2.2'
4+
display_version: '2.3.0'
55
start_page: index.adoc
66
nav:
77
- modules/ROOT/nav.adoc
88
asciidoc:
99
attributes:
1010
product-name: 'Spring-Data-Eclipse-Store'
11-
display-version: '2.2.2'
12-
maven-version: '2.2.2'
11+
display-version: '2.3.0'
12+
maven-version: '2.3.0'
1313
page-editable: false
1414
page-out-of-support: false

docs/modules/ROOT/pages/configuration.adoc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,24 @@ public class DemoConfiguration extends EclipseStoreClientConfiguration
2828
The method ``createEmbeddedStorageFoundation`` could return a much more complicated ``EmbeddedStorageFoundation`` as described here in the https://docs.eclipsestore.io/manual/storage/configuration/index.html[EclipseStore documentation about configuration and foundations].
2929

3030
This also enables you to use multiple EclipseStore-Storages in one project. See the https://github.com/xdev-software/spring-data-eclipse-store/tree/develop/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/dual/storage[Dual storages demo].
31+
32+
== Properties
33+
34+
In general properties from EclipseStore can be used.
35+
See https://docs.eclipsestore.io/manual/storage/configuration/properties.html[EclipseStore - Properties].
36+
37+
Here the {product-name}-Properties are displayed (all must be prefixed with ``spring-data-eclipse-store``):
38+
39+
[cols="1,1"]
40+
|===
41+
|https://github.com/xdev-software/spring-data-eclipse-store/tree/develop/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java[context-close-shutdown-storage.enabled] [[context-close-shutdown-storage]]
42+
| If enabled, the application listens to the ``ContextClosedEvent`` and shuts the storage down if the restart of the spring-dev-tools is enabled (see xref:known-issues.adoc#spring-dev-tools[Known issues] and https://docs.spring.io/spring-boot/api/java/org/springframework/boot/devtools/autoconfigure/DevToolsProperties.Restart.html[DevToolProperties])
43+
44+
Default: ``true``
45+
46+
|https://github.com/xdev-software/spring-data-eclipse-store/tree/develop/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java[context-close-shutdown-storage.only-when-dev-tools]
47+
|If this and ``context-close-shutdown-storage.enabled`` are true, the application listens to the ``ContextClosedEvent`` and shuts the storage down **only if** the spring-dev-tools are present in the ClassLoader (see xref:known-issues.adoc#spring-dev-tools[Known issues])
48+
49+
Default: ``true``
50+
51+

docs/modules/ROOT/pages/known-issues.adoc

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,14 @@ This helps you keep your data up to date regardless of the current version.
1818

1919
We created https://github.com/xdev-software/spring-data-eclipse-store/issues/33[an issue] for that but right now we *do not support XDEVs MicroMigration*.
2020

21-
== Spring Developer Tools
21+
== Spring Developer Tools [[spring-dev-tools]]
2222

2323
Using https://docs.spring.io/spring-boot/reference/using/devtools.html[Spring Developer Tools] (`spring-boot-devtools`) can lead to serious issues in your project.
24-
That is manly due to the https://docs.spring.io/spring-boot/reference/using/devtools.html#using.devtools.livereload[LiveReload feature] and the usage of a "Restart Classloader".
25-
26-
This leads to problems within EclipseStore and can cause issues with discovering beans (https://github.com/spring-projects/spring-boot/issues/41011[Example Issue]).
27-
28-
If you must use the Spring Developer Tools, make sure to https://docs.spring.io/spring-boot/reference/using/devtools.html#using.devtools.restart.disable[disable restart].
29-
30-
[source,java,title="Example how to disable restart"]
31-
----
32-
@SpringBootApplication
33-
public class MyApplication {
34-
public static void main(String[] args) {
35-
System.setProperty("spring.devtools.restart.enabled", "false");
36-
SpringApplication.run(MyApplication.class, args);
37-
}
38-
}
39-
----
24+
That is manly due to the https://docs.spring.io/spring-boot/reference/using/devtools.html#using.devtools.livereload[LiveReload feature] and the usage of a "Restart ClassLoader".
25+
It derives from the https://docs.eclipsestore.io/manual/misc/integrations/spring-boot.html#_spring_dev_tools[issue with EclipseStore].
26+
27+
To mitigate this issue, {product-name} listens to the closing of the Spring-Context and shuts down the storage.
28+
This **should** handle most problems with the ClassLoader.
29+
Restarting the storage leads to a reloading of all entities and may take some time, yet circumvents the Restart ClassLoader Issue.
30+
31+
The behavior can be configured through xref:configuration.adoc#context-close-shutdown-storage[Properties] and is implemented in the https://github.com/xdev-software/spring-data-eclipse-store/tree/develop/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java[EclipseStoreClientConfiguration.java].

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>software.xdev</groupId>
88
<artifactId>spring-data-eclipse-store-root</artifactId>
9-
<version>2.2.3-SNAPSHOT</version>
9+
<version>2.3.0-SNAPSHOT</version>
1010
<packaging>pom</packaging>
1111

1212
<organization>

spring-data-eclipse-store-benchmark/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
<parent>
66
<groupId>software.xdev</groupId>
77
<artifactId>spring-data-eclipse-store-root</artifactId>
8-
<version>2.2.3-SNAPSHOT</version>
8+
<version>2.3.0-SNAPSHOT</version>
99
</parent>
1010

1111
<artifactId>spring-data-eclipse-store-benchmark</artifactId>
12-
<version>2.2.3-SNAPSHOT</version>
12+
<version>2.3.0-SNAPSHOT</version>
1313
<packaging>jar</packaging>
1414

1515
<inceptionYear>2023</inceptionYear>

spring-data-eclipse-store-demo/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
<parent>
88
<groupId>software.xdev</groupId>
99
<artifactId>spring-data-eclipse-store-root</artifactId>
10-
<version>2.2.3-SNAPSHOT</version>
10+
<version>2.3.0-SNAPSHOT</version>
1111
</parent>
1212

1313
<artifactId>spring-data-eclipse-store-demo</artifactId>
14-
<version>2.2.3-SNAPSHOT</version>
14+
<version>2.3.0-SNAPSHOT</version>
1515
<packaging>jar</packaging>
1616

1717
<organization>

spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/ComplexConfiguration.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.nio.file.Path;
44

5+
import org.eclipse.serializer.reflect.ClassLoaderProvider;
56
import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties;
67
import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory;
78
import org.eclipse.store.storage.embedded.types.EmbeddedStorage;
@@ -28,10 +29,11 @@ public class ComplexConfiguration extends EclipseStoreClientConfiguration
2829
@Autowired
2930
public ComplexConfiguration(
3031
final EclipseStoreProperties defaultEclipseStoreProperties,
31-
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider
32+
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider,
33+
final ClassLoaderProvider classLoaderProvider
3234
)
3335
{
34-
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider);
36+
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider);
3537
}
3638

3739
/**
@@ -45,7 +47,11 @@ public ComplexConfiguration(
4547
@Override
4648
public EmbeddedStorageFoundation<?> createEmbeddedStorageFoundation()
4749
{
48-
return EmbeddedStorage.Foundation(Storage.Configuration(Storage.FileProvider(Path.of(STORAGE_PATH))));
50+
final EmbeddedStorageFoundation<?> storageFoundation =
51+
EmbeddedStorage.Foundation(Storage.Configuration(Storage.FileProvider(Path.of(STORAGE_PATH))));
52+
// This is only needed, if a different ClassLoader is used (e.g. when using spring-dev-tools)
53+
storageFoundation.getConnectionFoundation().setClassLoaderProvider(this.getClassLoaderProvider());
54+
return storageFoundation;
4955
}
5056

5157
/**

spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/dual/storage/invoice/PersistenceInvoiceConfiguration.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.nio.file.Path;
44

5+
import org.eclipse.serializer.reflect.ClassLoaderProvider;
56
import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties;
67
import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory;
78
import org.eclipse.store.storage.embedded.types.EmbeddedStorage;
@@ -23,15 +24,15 @@
2324
@EnableEclipseStoreRepositories
2425
public class PersistenceInvoiceConfiguration extends EclipseStoreClientConfiguration
2526
{
26-
2727
public static final String STORAGE_PATH = "storage-invoice";
2828

2929
@Autowired
3030
protected PersistenceInvoiceConfiguration(
3131
final EclipseStoreProperties defaultEclipseStoreProperties,
32-
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider)
32+
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider,
33+
final ClassLoaderProvider classLoaderProvider)
3334
{
34-
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider);
35+
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider);
3536
}
3637

3738
/**
@@ -45,6 +46,10 @@ protected PersistenceInvoiceConfiguration(
4546
@Override
4647
public EmbeddedStorageFoundation<?> createEmbeddedStorageFoundation()
4748
{
48-
return EmbeddedStorage.Foundation(Storage.Configuration(Storage.FileProvider(Path.of(STORAGE_PATH))));
49+
final EmbeddedStorageFoundation<?> storageFoundation =
50+
EmbeddedStorage.Foundation(Storage.Configuration(Storage.FileProvider(Path.of(STORAGE_PATH))));
51+
// This is only needed, if a different ClassLoader is used (e.g. when using spring-dev-tools)
52+
storageFoundation.getConnectionFoundation().setClassLoaderProvider(getClassLoaderProvider());
53+
return storageFoundation;
4954
}
5055
}

spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/dual/storage/person/PersistencePersonConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package software.xdev.spring.data.eclipse.store.demo.dual.storage.person;
22

3+
import org.eclipse.serializer.reflect.ClassLoaderProvider;
34
import org.eclipse.store.integrations.spring.boot.types.configuration.ConfigurationPair;
45
import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties;
56
import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory;
@@ -31,9 +32,10 @@ public class PersistencePersonConfiguration extends EclipseStoreClientConfigurat
3132
public PersistencePersonConfiguration(
3233
final EclipseStoreProperties defaultEclipseStoreProperties,
3334
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider,
34-
final EclipseStoreProperties properties)
35+
final EclipseStoreProperties properties,
36+
final ClassLoaderProvider classLoaderProvider)
3537
{
36-
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider);
38+
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider);
3739
this.foundation = defaultEclipseStoreProvider;
3840
this.properties = properties;
3941
}

spring-data-eclipse-store-jpa/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
<parent>
88
<groupId>software.xdev</groupId>
99
<artifactId>spring-data-eclipse-store-root</artifactId>
10-
<version>2.2.3-SNAPSHOT</version>
10+
<version>2.3.0-SNAPSHOT</version>
1111
</parent>
1212

1313
<artifactId>spring-data-eclipse-store-jpa</artifactId>
14-
<version>2.2.3-SNAPSHOT</version>
14+
<version>2.3.0-SNAPSHOT</version>
1515
<packaging>jar</packaging>
1616

1717
<inceptionYear>2023</inceptionYear>

spring-data-eclipse-store-jpa/src/test/java/software/xdev/spring/data/eclipse/store/jpa/integration/TestConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.nio.file.Path;
1919

20+
import org.eclipse.serializer.reflect.ClassLoaderProvider;
2021
import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties;
2122
import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory;
2223
import org.springframework.beans.factory.DisposableBean;
@@ -45,9 +46,10 @@ public class TestConfiguration extends EclipseStoreClientConfiguration implement
4546
@Autowired
4647
protected TestConfiguration(
4748
final EclipseStoreProperties defaultEclipseStoreProperties,
48-
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider)
49+
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider,
50+
final ClassLoaderProvider classLoaderProvider)
4951
{
50-
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider);
52+
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider);
5153
}
5254

5355
@EventListener

spring-data-eclipse-store/pom.xml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>software.xdev</groupId>
88
<artifactId>spring-data-eclipse-store</artifactId>
9-
<version>2.2.3-SNAPSHOT</version>
9+
<version>2.3.0-SNAPSHOT</version>
1010
<packaging>jar</packaging>
1111

1212
<name>spring-data-eclipse-store</name>
@@ -54,6 +54,10 @@
5454
<org.springframework.boot.version>3.3.4</org.springframework.boot.version>
5555
<org.eclipse.store.version>1.4.0</org.eclipse.store.version>
5656
<org.eclipse.serializer.version>1.4.0</org.eclipse.serializer.version>
57+
<hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
58+
<jakarta.el-api.version>6.0.1</jakarta.el-api.version>
59+
<expressly.version>6.0.0-M1</expressly.version>
60+
<hibernate-core.version>6.6.1.Final</hibernate-core.version>
5761
</properties>
5862

5963
<repositories>
@@ -164,6 +168,37 @@
164168
</exclusion>
165169
</exclusions>
166170
</dependency>
171+
172+
<dependency>
173+
<groupId>jakarta.validation</groupId>
174+
<artifactId>jakarta.validation-api</artifactId>
175+
</dependency>
176+
<dependency>
177+
<groupId>org.hibernate.validator</groupId>
178+
<artifactId>hibernate-validator</artifactId>
179+
<version>${hibernate-validator.version}</version>
180+
</dependency>
181+
<dependency>
182+
<groupId>org.hibernate.orm</groupId>
183+
<artifactId>hibernate-core</artifactId>
184+
<version>${hibernate-core.version}</version>
185+
<exclusions>
186+
<exclusion>
187+
<artifactId>antlr4-runtime</artifactId>
188+
<groupId>org.antlr</groupId>
189+
</exclusion>
190+
</exclusions>
191+
</dependency>
192+
<dependency>
193+
<groupId>jakarta.el</groupId>
194+
<artifactId>jakarta.el-api</artifactId>
195+
<version>${jakarta.el-api.version}</version>
196+
</dependency>
197+
<dependency>
198+
<groupId>org.glassfish.expressly</groupId>
199+
<artifactId>expressly</artifactId>
200+
<version>${expressly.version}</version>
201+
</dependency>
167202

168203
<dependency>
169204
<groupId>com.googlecode.cqengine</groupId>
@@ -288,7 +323,7 @@
288323
<plugin>
289324
<groupId>org.apache.maven.plugins</groupId>
290325
<artifactId>maven-javadoc-plugin</artifactId>
291-
<version>3.10.0</version>
326+
<version>3.10.1</version>
292327
<executions>
293328
<execution>
294329
<id>attach-javadocs</id>

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/importer/EclipseStoreDataImporter.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public EclipseStoreDataImporter(final EclipseStoreClientConfiguration configurat
5151
{
5252
this.configuration = configuration;
5353
}
54-
54+
5555
/**
5656
* Imports entities from all given {@link EntityManagerFactory}s that are available into the EclipseStore storage.
5757
* <p>
@@ -265,7 +265,9 @@ private <T> void createRepositoryForType(
265265
storageInstance,
266266
storageInstance,
267267
new SupportedChecker.Implementation(),
268-
storageInstance
268+
storageInstance,
269+
this.configuration.getValidator(),
270+
this.configuration.getClassLoaderProvider()
269271
),
270272
domainClass,
271273
new EclipseStoreTransactionManager(),

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.eclipse.serializer.persistence.binary.jdk17.java.util.BinaryHandlerImmutableCollectionsSet12;
2626
import org.eclipse.serializer.persistence.types.Storer;
2727
import org.eclipse.serializer.reference.ObjectSwizzling;
28+
import org.eclipse.serializer.reflect.ClassLoaderProvider;
2829
import org.eclipse.store.storage.embedded.types.EmbeddedStorageFoundation;
2930
import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager;
3031
import org.eclipse.store.storage.types.StorageManager;
@@ -69,6 +70,7 @@ public class EclipseStoreStorage
6970
*/
7071
private final Map<Class<?>, VersionManager<?>> versionManagers = new ConcurrentHashMap<>();
7172
private final EclipseStoreStorageFoundationProvider foundationProvider;
73+
private final ClassLoaderProvider classLoaderProvider;
7274
private EntitySetCollector entitySetCollector;
7375
private PersistableChecker persistenceChecker;
7476
private EmbeddedStorageManager storageManager;
@@ -81,6 +83,7 @@ public class EclipseStoreStorage
8183
public EclipseStoreStorage(final EclipseStoreClientConfiguration storeConfiguration)
8284
{
8385
this.foundationProvider = storeConfiguration;
86+
this.classLoaderProvider = storeConfiguration.getClassLoaderProvider();
8487
}
8588

8689
private StorageManager getInstanceOfStorageManager()
@@ -94,6 +97,11 @@ public WorkingCopyRegistry getRegistry()
9497
return this.registry;
9598
}
9699

100+
public ClassLoaderProvider getClassLoaderProvider()
101+
{
102+
return this.classLoaderProvider;
103+
}
104+
97105
private synchronized void ensureEntitiesInRoot()
98106
{
99107
if(this.storageManager == null)

0 commit comments

Comments
 (0)