Skip to content

Commit bfd7f13

Browse files
Merge pull request #200 from xdev-software/lazy-repositories
Lazy repositories
2 parents ca2ed46 + 911c2fa commit bfd7f13

File tree

99 files changed

+2512
-224
lines changed

Some content is hidden

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

99 files changed

+2512
-224
lines changed

.github/workflows/check-build.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,6 @@ jobs:
117117
- name: Run PMD
118118
run: ./mvnw -B test pmd:aggregate-pmd-no-fork pmd:check -P pmd -DskipTests -T2C
119119

120-
- name: Run CPD (Copy Paste Detector)
121-
run: ./mvnw -B pmd:aggregate-cpd pmd:cpd-check -P pmd -DskipTests -T2C
122-
123120
- name: Upload report
124121
if: always()
125122
uses: actions/upload-artifact@v4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ spring-data-eclipse-store-demo/storage
6767
spring-data-eclipse-store-demo/storage-person
6868
spring-data-eclipse-store-demo/storage-invoice
6969
spring-data-eclipse-store-demo/storage-complex
70+
spring-data-eclipse-store-demo/storage-lazy
7071
spring-data-eclipse-store-jpa/storage-eclipsestore
7172
spring-data-eclipse-store-jpa/storage-h2.mv.db
7273
spring-data-eclipse-store-jpa/storage-h2.trace.db

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Updated org.springframework.boot.version to v3.4.0
44
* Updated EclipseStore to v2.0.0
5+
* Implemented Lazy Repositories with ``LazyEclipseStoreRepository``
56

67
# 2.3.1
78

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ the [demos](./spring-data-eclipse-store-demo):
6666

6767
* [Simple demo](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/simple)
6868
* [Complex demo](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/complex)
69+
* [Lazy demo](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/lazy)
6970
* [Demo with coexisting JPA](https://github.com/xdev-software/spring-data-eclipse-store/tree/develop/spring-data-eclipse-store-jpa/src/main/java/software/xdev/spring/data/eclipse/store/jpa)
7071
* [Dual storage demo](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)
7172

docs/modules/ROOT/pages/features/lazies.adoc

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,38 @@ public class Owner extends Person
2727
{
2828
private String address;
2929
30-
private Lazy<List<Pet>> pets = SpringDataEclipseStoreLazy.build(new ArrayList<>());
30+
private final Lazy<List<Pet>> pets = SpringDataEclipseStoreLazy.build(new ArrayList<>());
3131
//...
3232
----
3333

34+
== Repositories
35+
36+
Entities in a repository are by default **not lazy**.
37+
But we made it as easy as possible for you to make these entities lazy: Instead of extending the ``EclipseStoreRepository`` (or any similar class from the ``software.xdev.spring.data.eclipse.store.repository.interfaces``-Package), you simply extend the ``LazyEclipseStoreRepository``.
38+
39+
=== 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/lazy/CustomerRepository.java[Example from lazy demo]
40+
41+
[source,java,title="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/simple/CustomerRepository.java[Before (not lazy)]"]
42+
----
43+
public interface CustomerRepository extends CrudRepository<Customer, String>
44+
{
45+
}
46+
----
47+
48+
[source,java,title="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/lazy/CustomerRepository.java[After (lazy)]"]
49+
----
50+
public interface CustomerRepository extends LazyEclipseStoreCrudRepository<Customer, String>
51+
{
52+
}
53+
----
54+
55+
Every instance of the ``Customer``-Entities are now wrapped in a https://docs.eclipsestore.io/manual/storage/loading-data/lazy-loading/index.html[``Lazy``-Reference].
56+
That means that these objects are **only loaded from the storage, if they are needed** e.g. when ``findAll`` is called.
57+
58+
The method **``findById`` only loads the entities with the corresponding IDs**, because a separate list with all ids is stored.
59+
But if any method like **``findByName`` or ``findByChild`` is used, all objects are loaded** from the storage.
60+
This is currently the only way to get the actual values of the entities.
61+
3462
== Internals
3563

3664
SpringDataEclipseStoreLazies work as a proxy for the EclipseStore-Lazies.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package software.xdev.spring.data.eclipse.store.demo.lazy;
2+
3+
import jakarta.persistence.GeneratedValue;
4+
import jakarta.persistence.GenerationType;
5+
6+
import org.springframework.data.annotation.Id;
7+
8+
9+
public class Customer
10+
{
11+
@Id
12+
@GeneratedValue(strategy = GenerationType.AUTO)
13+
private String id;
14+
15+
private final String firstName;
16+
private final String lastName;
17+
18+
public Customer(final String firstName, final String lastName)
19+
{
20+
this.firstName = firstName;
21+
this.lastName = lastName;
22+
}
23+
24+
@Override
25+
public String toString()
26+
{
27+
return String.format(
28+
"Customer[id=%s, firstName='%s', lastName='%s']",
29+
this.id, this.firstName, this.lastName);
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package software.xdev.spring.data.eclipse.store.demo.lazy;
2+
3+
import software.xdev.spring.data.eclipse.store.repository.interfaces.lazy.LazyEclipseStoreCrudRepository;
4+
5+
6+
public interface CustomerRepository extends LazyEclipseStoreCrudRepository<Customer, String>
7+
{
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package software.xdev.spring.data.eclipse.store.demo.lazy;
2+
3+
import java.nio.file.Path;
4+
5+
import org.eclipse.serializer.reflect.ClassLoaderProvider;
6+
import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties;
7+
import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory;
8+
import org.eclipse.store.storage.embedded.types.EmbeddedStorage;
9+
import org.eclipse.store.storage.embedded.types.EmbeddedStorageFoundation;
10+
import org.eclipse.store.storage.types.Storage;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.context.annotation.Configuration;
13+
14+
import software.xdev.spring.data.eclipse.store.demo.dual.storage.person.PersistencePersonConfiguration;
15+
import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreClientConfiguration;
16+
import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories;
17+
18+
19+
@Configuration
20+
@EnableEclipseStoreRepositories
21+
public class LazyConfiguration extends EclipseStoreClientConfiguration
22+
{
23+
24+
public static final String STORAGE_PATH = "storage-lazy";
25+
26+
@Autowired
27+
public LazyConfiguration(
28+
final EclipseStoreProperties defaultEclipseStoreProperties,
29+
final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider,
30+
final ClassLoaderProvider classLoaderProvider
31+
)
32+
{
33+
super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider);
34+
}
35+
/**
36+
* This is one option how to configure the {@link EmbeddedStorageFoundation}.
37+
* <p>
38+
* We create a completely new foundation. That means that all configuration (e.g. properties) are not used here.
39+
* With this method you have complete control over the configuration.
40+
* </p>
41+
* Another example: {@link PersistencePersonConfiguration#createEmbeddedStorageFoundation()}
42+
*/
43+
@Override
44+
public EmbeddedStorageFoundation<?> createEmbeddedStorageFoundation()
45+
{
46+
final EmbeddedStorageFoundation<?> storageFoundation =
47+
EmbeddedStorage.Foundation(Storage.Configuration(Storage.FileProvider(Path.of(STORAGE_PATH))));
48+
// This is only needed, if a different ClassLoader is used (e.g. when using spring-dev-tools)
49+
storageFoundation.getConnectionFoundation().setClassLoaderProvider(this.getClassLoaderProvider());
50+
return storageFoundation;
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2012-2019 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 software.xdev.spring.data.eclipse.store.demo.lazy;
18+
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
21+
import org.springframework.boot.CommandLineRunner;
22+
import org.springframework.boot.SpringApplication;
23+
import org.springframework.boot.autoconfigure.SpringBootApplication;
24+
25+
26+
@SpringBootApplication
27+
public class LazyDemoApplication implements CommandLineRunner
28+
{
29+
private static final Logger LOG = LoggerFactory.getLogger(LazyDemoApplication.class);
30+
private final CustomerRepository customerRepository;
31+
private final PetRepository petRepository;
32+
33+
public LazyDemoApplication(
34+
final CustomerRepository customerRepository,
35+
final PetRepository petRepository
36+
)
37+
{
38+
this.customerRepository = customerRepository;
39+
this.petRepository = petRepository;
40+
}
41+
42+
public static void main(final String[] args)
43+
{
44+
SpringApplication.run(LazyDemoApplication.class, args);
45+
}
46+
47+
@Override
48+
public void run(final String... args)
49+
{
50+
this.customerRepository.deleteAll();
51+
52+
// save a couple of customers
53+
this.customerRepository.save(new Customer("Stevie", "Nicks"));
54+
this.customerRepository.save(new Customer("Mick", "Fleetwood"));
55+
56+
// fetch all customers
57+
LOG.info("Customers found with findAll():");
58+
this.customerRepository.findAll().forEach(c -> LOG.info(c.toString()));
59+
60+
// save a pet
61+
this.petRepository.save(new Pet("1", "Peter", 2));
62+
63+
// fetch all pets
64+
LOG.info("Pets found with findAll():");
65+
this.petRepository.findAll().forEach(p -> LOG.info(p.toString()));
66+
}
67+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package software.xdev.spring.data.eclipse.store.demo.lazy;
2+
3+
import org.springframework.data.annotation.Id;
4+
5+
6+
public class Pet
7+
{
8+
@Id
9+
private String id;
10+
11+
private String name;
12+
private Integer age;
13+
14+
public Pet()
15+
{
16+
}
17+
18+
public Pet(final String id, final String name, final Integer age)
19+
{
20+
this.id = id;
21+
this.name = name;
22+
this.age = age;
23+
}
24+
25+
@Override
26+
public String toString()
27+
{
28+
return String.format(
29+
"Pet[id=%s, name='%s', age='%s']",
30+
this.id, this.name, this.age);
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package software.xdev.spring.data.eclipse.store.demo.lazy;
2+
3+
import software.xdev.spring.data.eclipse.store.repository.interfaces.lazy.LazyEclipseStoreCrudRepository;
4+
5+
6+
public interface PetRepository extends LazyEclipseStoreCrudRepository<Pet, String>
7+
{
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package software.xdev.spring.data.eclipse.store.demo.lazy.complex;
2+
3+
import java.io.File;
4+
5+
import org.junit.jupiter.api.BeforeAll;
6+
import org.junit.jupiter.api.Test;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.boot.test.context.SpringBootTest;
9+
10+
import software.xdev.spring.data.eclipse.store.demo.TestUtil;
11+
import software.xdev.spring.data.eclipse.store.demo.lazy.LazyConfiguration;
12+
import software.xdev.spring.data.eclipse.store.demo.lazy.LazyDemoApplication;
13+
import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreClientConfiguration;
14+
15+
16+
@SpringBootTest(classes = LazyDemoApplication.class)
17+
class LazyDemoApplicationTest
18+
{
19+
private final EclipseStoreClientConfiguration configuration;
20+
21+
@Autowired
22+
public LazyDemoApplicationTest(final LazyConfiguration configuration)
23+
{
24+
this.configuration = configuration;
25+
}
26+
27+
@BeforeAll
28+
static void clearPreviousData()
29+
{
30+
TestUtil.deleteDirectory(new File("./" + LazyConfiguration.STORAGE_PATH));
31+
}
32+
33+
@Test
34+
void checkPossibilityToSimplyStartAndRestartApplication()
35+
{
36+
this.configuration.getStorageInstance().stop();
37+
LazyDemoApplication.main(new String[]{});
38+
}
39+
}

spring-data-eclipse-store/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@
314314
<artifactId>maven-compiler-plugin</artifactId>
315315
<version>3.13.0</version>
316316
<configuration>
317+
<source>${javaVersion}</source>
318+
<target>${javaVersion}</target>
317319
<release>${maven.compiler.release}</release>
318320
<compilerArgs>
319321
<arg>-proc:none</arg>

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityListProvider.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,4 @@
1818
public interface EntityListProvider
1919
{
2020
<T, ID> EntityProvider<T, ID> getEntityProvider(final Class<T> clazz);
21-
22-
<T> long getEntityCount(final Class<T> clazz);
2321
}

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityProvider.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
import java.util.ArrayList;
1919
import java.util.Collection;
2020
import java.util.List;
21+
import java.util.Objects;
2122
import java.util.Optional;
22-
import java.util.Set;
2323
import java.util.stream.Collectors;
2424
import java.util.stream.Stream;
2525

26-
import software.xdev.spring.data.eclipse.store.repository.root.EntityData;
26+
import software.xdev.spring.data.eclipse.store.repository.root.v2_4.EntityData;
2727

2828

2929
@SuppressWarnings("java:S119")
@@ -38,7 +38,7 @@ public void addEntityData(final EntityData<? extends T, ID> entityData)
3838

3939
public Stream<? extends T> stream()
4040
{
41-
return this.entityDataList.stream().map(EntityData::getEntities).flatMap(Set::stream);
41+
return this.entityDataList.stream().flatMap(EntityData::getEntitiesAsStream);
4242
}
4343

4444
public Collection<T> toCollection()
@@ -56,12 +56,13 @@ public long size()
5656
return this.stream().count();
5757
}
5858

59+
@SuppressWarnings("unchecked")
5960
public Optional<T> findAnyEntityWithId(final ID id)
6061
{
6162
return (Optional<T>)this.entityDataList
6263
.stream()
63-
.map(entityData -> entityData.getEntitiesById().get(id))
64-
.filter(e -> e != null)
64+
.map(entityData -> entityData.getEntityById(id))
65+
.filter(Objects::nonNull)
6566
.findAny();
6667
}
6768
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@
2525
import software.xdev.micromigration.version.MigrationVersion;
2626
import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot;
2727
import software.xdev.spring.data.eclipse.store.repository.root.update.scripts.v2_0_0_InitializeVersioning;
28+
import software.xdev.spring.data.eclipse.store.repository.root.update.scripts.v2_4_0_InitializeLazy;
2829

2930

3031
public final class EclipseStoreMigrator
3132
{
3233
public static final VersionAgnosticMigrationScript<?, ?>[] SCRIPTS =
3334
new VersionAgnosticMigrationScript[]{
34-
new v2_0_0_InitializeVersioning()
35+
new v2_0_0_InitializeVersioning(),
36+
new v2_4_0_InitializeLazy()
3537
};
3638

3739
private EclipseStoreMigrator()

0 commit comments

Comments
 (0)