Comments (34)
I just released version 1.1.5
and 2.1.6
which contains a fix for this bug.
from spring-data.
@bthj-tms I think I've fixed this issue with PR #57.
@mpv1989 can you please have a look at PR #57?
from spring-data.
Sets will be supported with the next release.
from spring-data.
They are annotated with
@Relations(..., lazy=true)
and if I do nothing to trigger the lazy loading - likeactor.getMovies.size()
- they are still returned as populated.
By "populated" you mean serialized by Jackson to JSON? Keep in mind that Jackson triggers the resolution of the lazy loading class with its serialization process (by accessing it).
actor.setMovies(null); return actor;
and so limiting the data being returned to the client, but am I then limiting the data being transferred from the database and reducing querying overhead?
If you don't access movies before you set them to null
, they are not loaded from the DB. So yes, you can reduce querying effort with this approach.
from spring-data.
Thanks for explaining how this works. That's what I meant by populated.
from spring-data.
The cause of the stack overflow is a cyclic reference: Actor -> Role -> Actor -> ...
Use lazy=true on one of the From annotations to break the cycle.
from spring-data.
If there's no advantage (in the context of requirements), i'd personally use @ Ref instead of From or To. And for me Ref of List type acted lazily by default.
P.S. This might also be pointing to different laziness semantics for From & Ref, which would probably be a bug that's worth logging (& addressing).
P.P.S. For comparison, all -to-many associations are lazily loaded in JPA by default:
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/OneToMany.html#fetch--
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/ManyToMany.html#fetch--
(and while JPA implementations are allowed to be eager for stuff that is
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/FetchType.html#LAZY
i don't see why they would ever be).
from spring-data.
@christian-lechner thanks. there's a similar type of issue that occurs in the neo4j spring data, but it's addressed differently. in this case, the lazy = true setting didn't work. I tried adding the lazy config - first on the Doc's @ From, then Edge's @ From (see below as example). both returned errors.
public class Actor {
....
@From(lazy = true)
public List<Role> roles;
....
}
public class Role {
....
@From(lazy = true)
private Actor actor;
....
}
in both cases, the error returned was:
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
in this specific case, I only have one actor and three movies (which means three edges). what is somewhat interesting is when I put the @ From (lazy=true) on the Actor (only one actor), I get the above error once. When I put that same annotation on the Role (3 roles), I get the error three times. I could be wrong, but it seems it is reading the data out just not mapping it correctly.
@haqer1 I would LOVE to use @ Ref, but the client requirement is graph. Ultimately, I want to be able to get back the edges for a delete operation. I can write the AQL, but it seemed like using the @ To and @ From would - longer term - work better. For devs not familiar with AQL that might take over or have to change, having the abstracted stuff has advantages.
from spring-data.
And for me Ref of List type acted lazily by default.
That's not possible. All relations are loaded eagerly by default.
@nordgreg
The lazy=true
is the solution for your stack overflow error. The new exception is interesting. Which OS and Java version do you use? Can you try with "normal" getter method (without lombok generated one)?
from spring-data.
OS and Java version do you use?
mac os and 1.8.0_161.
Can you try with "normal" getter method (without lombok generated one)?
yes. same error.
from spring-data.
there's a similar type of issue that occurs in the neo4j spring data, but it's addressed differently.
Do you have a link for us?
Can you provide an easy example in a repo that we can clone and reproduce the problem?
from spring-data.
having trouble finding the neo4j example. it was a while ago when I was working on it :)
i'll put together the repo as soon as I can.
from spring-data.
I put together a small example: movie-platform-test. This works fine on my machine. Can you try it please?
A Google search shows that the cause may be an infinite recursion. Can you post the complete stack trace?
from spring-data.
wow. thank you for doing that.
i'll try it out today.
from spring-data.
fyi, we're not on spring-boot 2.0, therefore still on spring-arango 1.x
moving to boot 2.0 is likely not an option - unfortunately.
from spring-data.
I downgraded the dependencies to spring-boot 1.5.12 and spring-data-arangodb 1.1.2. Still working on my machine ;)
from spring-data.
thanks, @christian-lechner. first, thanks again for looking at this. there's definitely acceptable work-arounds to meet the goal.
that said, I will post it asap. got another, unrelated priority issue I need to address.
from spring-data.
I would be really interested in your use case and which work-arounds are necessary to meet your goal. Are these work-arounds necessary due to bugs or limitations in this project?
from spring-data.
Are these work-arounds necessary due to bugs or limitations in this project?
maybe a bit of both. workaround might not be the best word choice...i'm just accomplishing the same thing using AQL. I'd prefer to use the library, but if it works, it works :)
from spring-data.
@nordgreg do you have any further information for us about this issue?
from spring-data.
In the movie-platform-test, what would be the correct way of including / annotating a
List<Actor> actors
in the Movie
class
and including
List<Movie> movies
in the Actor
class
?
Annotating both the above lists with
@Relations(edges = Role.class, lazy = true)
would probably produce the "java.lang.instrument ASSERTION FAILED..." error.
With JPA against an SQL database I'd annotate both those lists with @ManyToMany
(and @JoinTable
on one of them).
from spring-data.
You need to set on at least one of the @Relations
annotations the lazy=true
attribute. Otherwise you will get a stack overflow error (Movie - > Actor -> Movie -> ...).
We still do not know how @nordgreg produced the java.lang.instrument ASSERTION FAILED...
error, because he hasn't provided any details since then.
But you shouldn't get that error. This issue refers to a prev version of the movie platform test: see here.
from spring-data.
I've tried setting lazy=true
on both or one of the @Relations
, and in both cases I'm producing this java.lang.instrument ASSERTION FAILED
error - but I'm not doing exactly the same things as @nordgreg, as I'm not placing List<Role> roles
within one of the entity classes but rather List<OneEntity>
within AnotherEntity
.
What I'm then doing is similar to:
- Saving an
Actor
instance, which has aList<Movie>
attribute annotated with@Relations(...lazy=true)
- Save each element in
Actor
'sList<Movie>
(whereMovie
has aList<Actor>
attribute annotated with@Relations(...lazy=true)
) - Save an instance of
Role
for eachActor
-Movie
relation.
If I remove the annotation @Relations(edges = Role.class, lazy = true)
from List<Actor>
in Movie
, I get rid of the error.
I'm using version 1.1.3 of arangodb-spring-data with spring boot version 1.5.13.RELEASE.
from spring-data.
Ok, that's quite "cool" ;) Then we should have a setting were we can reproduce this error. I will try to reproduce it with your setup.
from spring-data.
@christian-lechner thanks a lot
@bthj-tms @nordgreg I will release a new version asap
from spring-data.
@mpv1989 Awesome!
Quite difficult to find the source of the infinite recursion. I got many exceptions while running/debugging, but none of them was a java.lang.instrument ASSERTION FAILED
error or a stack overflow error. Maybe the JVM went crazy because of the proxy classes.
@bthj-tms Thanks for pointing us in the right direction.
from spring-data.
@mpv1989 You were too fast releasing new versions. With my PR I'm mixing the container type and the component type. We need to fix it differently.
from spring-data.
@mpv1989 to return the list is ok, as it was before. I mixed component and container type. I'll try a better fix. Is there a chat or something where I can reach you better and keep you from publishing the next time :D
from spring-data.
@christian-lechner you can join our community slack
from spring-data.
Thank you so much, @christian-lechner and @mpv1989 - I can confirm that the error is gone with version 1.1.5
.
Another related question:
How can I populate a collection annotated with @Relations(edges = Clazz.class, lazy = true)
?
If I return the results through a REST endpoint based on Jackson, I get the error
JsonMappingException: object is not an instance of declaring class
If I change the annotation to declare lazy = false
on one side (the one I'm returning), things work fine and the collection - let's say actors
within Movie
- is populated. But if wanted to have movies
within Actor
to be populated (when returning Actor), I can't change its @Relations
to declare lazy = false
, as then things blow up (probably because of circular dependencies). So in that case, I probably want to manually populate that lazy relation - I've tried something like
Iterable<Actor> actors = actorRepository.findAll();
actors.forEach( a -> a.getMovies().size() );
return actors;
in an effort to initialize the lazy association, but that just gives me the error:
java.lang.IllegalArgumentException: object is not an instance of declaring class
from spring-data.
The proxy class should not hinder Jackson from serializing.
Have you used a Set
instead of a List
or a Collection
on the fields annotated with @Relation(..., lazy=true)
?
or
Do you have messed with your classpath and have two different class loaders present? You should check your imports. Do you have two classes with the same name? Check the _class
attribute of your actors and movies in the DB: it should contain the fully qualified class name. Does it differ from the one you've imported in your class?
The next thing you must do, if you want to serialize cyclic data with Jackson: http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
from spring-data.
Thanks for the hints.
In fact I was using a Set
, as that's supposed to be good for @ManyToMany
mappings with JPA, but have now changed to List
.
The solution for me was to set something like
@JsonIgnoreProperties("actors")
List<Movie> movies;
and
@JsonIgnoreProperties("movies")
List<Actor> actors;
as suggested in http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html
from spring-data.
One more question:
Now that I have related collections loading and returning fine, I wonder how I stop them from loading:
They are annotated with @Relations(..., lazy=true)
and if I do nothing to trigger the lazy loading - like actor.getMovies.size()
- they are still returned as populated.
I can do:
...
actor.setMovies(null);
return actor;
and so limiting the data being returned to the client, but am I then limiting the data being transferred from the database and reducing querying overhead?
from spring-data.
I'm assuming the problem does not exists anymore. I'll close this issue, feel free to open it again if the problem still persists
from spring-data.
Related Issues (20)
- Batch insert Docs or Edges with designated collection name HOT 1
- [DE-684] confuse about some code HOT 5
- Feature: allow embedded entities instead of resolvers HOT 2
- [DE-805] A way to check if a LazyLoadingProxy entity has been resolved HOT 2
- How can I get it to use the ArangoDBAsync driver? HOT 4
- spring boot- failed to load ApplicationContext HOT 1
- How to insert a large amount of data with good performance? HOT 2
- [DE-682] unify exception handling HOT 3
- Link to "Getting Started" is broken HOT 1
- DefaultArangoConverter and TypeInformation quality HOT 2
- [Query]Arangodb nested attribute sorting spring data HOT 2
- com.arangodb.ArangoDBException: Response: 400, Error: 1553 - bind parameter '@col' has an invalid value or type HOT 10
- CRUD Repository save and saveAll should return fetched entity instead of original HOT 1
- Support spring boot 3.2.0 HOT 1
- Version 4.0.0 (latest release) is not compatible with driver versions >7.1.0 HOT 1
- @CreatedDate fields not populated when inserting objects with user IDs. HOT 4
- Version 4.0.0 (latest release) is not compatible with driver versions >7.1.1 HOT 2
- [DE-771] Issue with running queries in stream transaction HOT 11
- Error when using VST Protocol HOT 2
- Call SimpleArangoRepository.findAllById concurrent with trigger ConcurrentModificationException exception HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-data.