Skip to content

Commit 6f9f53c

Browse files
Added docs and demos for lazy
1 parent 5335fac commit 6f9f53c

9 files changed

Lines changed: 79 additions & 28 deletions

File tree

CHANGELOG.md

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

33
* Added possibility to use multiple storages
4+
* Added Lazy support
45

56
# 1.0.3
67

docs/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
* xref:installation.adoc[Installation]
33
* xref:configuration.adoc[Configuration]
44
* xref:working-copies.adoc[Working Copies]
5+
* xref:lazies.adoc[Lazy References]
56
* xref:migration.adoc[Migration]
67
* xref:known-issues.adoc[Known issues]

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
= Known issues
22

3-
== Lazy references
4-
5-
One of the core features of EclipseStore is its https://docs.eclipsestore.io/manual/storage/loading-data/lazy-loading/index.html[Lazy references].
6-
Unfortunately this requires our library to implement some kind of proxy.
7-
That's something that takes a lot of effort to implement in our {product-name}.
8-
9-
We created https://github.com/xdev-software/spring-data-eclipse-store/issues/31[an issue] for that but right now we *do not support Lazy references*.
10-
113
== Query annotations
124

135
In Spring-Data-JPA you can write a Query over methods of repositories like this:
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
= Lazy References
2+
3+
Lazy Loading is an essential part of EclipseStore.
4+
The basic mechanism is best explained in the https://docs.eclipsestore.io/manual/storage/loading-data/lazy-loading/index.html[EclipseStore-Docs]. +
5+
In essence java objects which are wrapped in a *Lazy-Reference are not loaded with the startup of the EclipseStore-Storage but only if ``get()`` is called* on them.
6+
7+
Lazy References are essential for big data sets that can't get loaded into memory.
8+
Since {product-name} operates with xref:working-copies.adoc[working copies] using the EclipseStore-Lazy-References is not possible.
9+
All Lazy References would be resolved and loaded into memory anyway.
10+
11+
That's why we implemented ``SpringDataEclipseStoreLazy``. +
12+
The usage is the same as with the EclipseStore-Lazies, but they are handled very differently.
13+
14+
Simply wrap any kind of java object in the SpringDataEclipseStoreLazy-Wrapper and the wrapped object has a lazy loading behaviour.
15+
16+
CAUTION: Lazy-References are not only loaded when needed, but also https://docs.eclipsestore.io/manual/storage/loading-data/lazy-loading/clearing-lazy-references.html#automatically[*cleared when they are no longer needed*]!
17+
18+
Example: ``SpringDataEclipseStoreLazy.build(new HashMap<String, Pet>())``
19+
20+
[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/complex/owner/Owner.java[Example from complex demo]"]
21+
----
22+
package software.xdev.spring.data.eclipse.store.demo.complex.owner;
23+
//...
24+
import software.xdev.spring.data.eclipse.store.repository.lazy.SpringDataEclipseStoreLazy;
25+
26+
public class Owner extends Person
27+
{
28+
private String address;
29+
30+
private Lazy<List<Pet>> pets = SpringDataEclipseStoreLazy.build(new ArrayList<>());
31+
//...
32+
----
33+
34+
== Internas
35+
36+
SpringDataEclipseStoreLazies work as a proxy for the EclipseStore-Lazies.
37+
As far as EclipseStore is concerned, a SpringDataEclipseStoreLazy-Object is a normal Java object that contains a Lazy-Reference.
38+
39+
But when {product-name} creates the working copy, *the SpringDataEclipseStoreLazy-Reference is not resolved* but instead only a reference to the original Lazy-Object in EclipseStore is loaded.
40+
As soon as ``get()`` is called on the SpringDataEclipseStoreLazy, a *new working copy of the lazy object* is created.

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ public void run(final String... args)
103103
);
104104
}
105105
);
106+
107+
LOG.info("----Owner-Lazy Pet loading----");
108+
this.ownerRepository.findAll().forEach(
109+
o -> o.getPets().forEach(
110+
pet -> LOG.info(String.format(
111+
"Pet %s has owner %s %s",
112+
pet.getName(),
113+
o.getFirstName(),
114+
o.getLastName()))
115+
)
116+
);
106117
}
107118

108119
private static Visit createVisit()

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
import java.util.List;
2020
import java.util.Optional;
2121

22+
import org.eclipse.serializer.reference.Lazy;
2223
import org.springframework.core.style.ToStringCreator;
2324
import org.springframework.util.Assert;
2425

2526
import software.xdev.spring.data.eclipse.store.demo.complex.model.Person;
27+
import software.xdev.spring.data.eclipse.store.repository.lazy.SpringDataEclipseStoreLazy;
2628

2729

2830
public class Owner extends Person
@@ -33,7 +35,7 @@ public class Owner extends Person
3335

3436
private String telephone;
3537

36-
private final List<Pet> pets = new ArrayList<>();
38+
private Lazy<List<Pet>> pets = SpringDataEclipseStoreLazy.build(new ArrayList<>());
3739

3840
public String getAddress()
3941
{
@@ -52,7 +54,12 @@ public String getTelephone()
5254

5355
public List<Pet> getPets()
5456
{
55-
return this.pets;
57+
return this.pets.get();
58+
}
59+
60+
public void setPets(final List<Pet> pets)
61+
{
62+
this.pets = SpringDataEclipseStoreLazy.build(pets);
5663
}
5764

5865
public void addPet(final Pet pet)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package software.xdev.spring.data.eclipse.store.demo.complex.owner;
1717

18+
import java.util.List;
19+
1820
import org.springframework.data.domain.Page;
1921
import org.springframework.data.domain.Pageable;
2022
import org.springframework.data.repository.Repository;
@@ -28,5 +30,7 @@ public interface OwnerRepository extends Repository<Owner, Integer>
2830

2931
Page<Owner> findAll(Pageable pageable);
3032

33+
List<Owner> findAll();
34+
3135
void deleteAll();
3236
}

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

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
* {@link Lazy}-Wrapper!</b> Because SDES is making working copies of the stored data, the {@link Lazy} does not work as
3333
* expected. Instead, use this Wrapper. It brings the same functionality as the native {@link Lazy}-Wrapper but works
3434
* with working copies.
35+
*
36+
* @param <T> the type of the lazily referenced element
3537
*/
3638
public interface SpringDataEclipseStoreLazy<T> extends Lazy<T>
3739
{
@@ -57,19 +59,20 @@ static <T> SpringDataEclipseStoreLazy.Default<T> buildWithLazy(final Lazy<T> laz
5759
}
5860

5961
/**
60-
* This class is very complex and its various membervariables all have their reason to exist. This code is very
62+
* This class is very complex and its various member variables all have their reason to exist. This code is very
6163
* difficult to read due to its the functionality explained in the {@link SpringDataEclipseStoreLazyBinaryHandler}.
6264
*
63-
* @param <T>
65+
* @param <T> the type of the lazily referenced element
6466
*/
67+
@SuppressWarnings({"java:S2065", "checkstyle:FinalClass"})
6568
class Default<T> implements SpringDataEclipseStoreLazy<T>
6669
{
6770
private T objectToBeWrapped;
6871
private Lazy<T> wrappedLazy;
6972
private long objectId = Swizzling.notFoundId();
7073
private transient ObjectSwizzling loader;
7174
private transient WorkingCopier<T> copier;
72-
private transient boolean isStored = false;
75+
private transient boolean isStored;
7376

7477
private Default(final Lazy<T> lazySubject)
7578
{
@@ -99,10 +102,10 @@ private Lazy<T> ensureLazy()
99102
return this.wrappedLazy;
100103
}
101104

105+
@SuppressWarnings("unchecked")
102106
private Lazy<T> createNewDefaultLazyWithClearableReference()
103107
{
104108
Objects.requireNonNull(this.loader);
105-
Objects.requireNonNull(this.objectId);
106109
Objects.requireNonNull(this.copier);
107110

108111
final T originalInstance = (T)this.loader.getObject(this.objectId);
@@ -115,13 +118,6 @@ private Lazy<T> createNewDefaultLazyWithClearableReference()
115118
);
116119
}
117120

118-
@SuppressWarnings("all")
119-
public static final Class<SpringDataEclipseStoreLazy.Default<?>> genericType()
120-
{
121-
// no idea how to get ".class" to work otherwise in conjunction with generics.
122-
return (Class)SpringDataEclipseStoreLazy.Default.class;
123-
}
124-
125121
@Override
126122
public T get()
127123
{
@@ -195,9 +191,9 @@ public boolean clear(final ClearingEvaluator clearingEvaluator)
195191
@Override
196192
public long objectId()
197193
{
198-
if(this.wrappedLazy != null && this.wrappedLazy instanceof Lazy.Default<T>)
194+
if(this.wrappedLazy != null && this.wrappedLazy instanceof final Lazy.Default<T> wrappedTypedLazy)
199195
{
200-
return ((Lazy.Default<T>)this.wrappedLazy).objectId();
196+
return wrappedTypedLazy.objectId();
201197
}
202198
return this.objectId;
203199
}
@@ -217,7 +213,7 @@ public T getObjectToBeWrapped()
217213
@Override
218214
public SpringDataEclipseStoreLazy<T> copyWithReference()
219215
{
220-
final SpringDataEclipseStoreLazy.Default newLazy = new SpringDataEclipseStoreLazy.Default(
216+
final SpringDataEclipseStoreLazy.Default<T> newLazy = new SpringDataEclipseStoreLazy.Default<>(
221217
this.objectId(),
222218
this.loader,
223219
this.copier
@@ -226,18 +222,17 @@ public SpringDataEclipseStoreLazy<T> copyWithReference()
226222
return newLazy;
227223
}
228224

229-
// TODO is this necessary?
230225
@Override
231226
public void unlink()
232227
{
233228
try
234229
{
235230
if(this.wrappedLazy != null)
236231
{
237-
final Lazy.Default wrappedDefaultLazy = (Lazy.Default)this.wrappedLazy;
232+
final Lazy.Default<T> wrappedDefaultLazy = (Lazy.Default<T>)this.wrappedLazy;
238233
wrappedDefaultLazy.$unlink();
239234
final Field objectIdField = Lazy.Default.class.getDeclaredField("objectId");
240-
try(final FieldAccessModifier fam = FieldAccessModifier.prepareForField(
235+
try(final FieldAccessModifier<Lazy.Default<T>> fam = FieldAccessModifier.prepareForField(
241236
objectIdField,
242237
wrappedDefaultLazy))
243238
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public SpringDataEclipseStoreLazyBinaryHandler(
7676
final WorkingCopier<?> copier)
7777
{
7878
super(
79-
SpringDataEclipseStoreLazy.Default.genericType(),
79+
(Class)SpringDataEclipseStoreLazy.Default.class,
8080
CustomFields(
8181
CustomField(Object.class, "lazySubject"),
8282
CustomField(Object.class, "unwrappedSubject")

0 commit comments

Comments
 (0)