Giter VIP home page Giter VIP logo

Comments (34)

mvollmary avatar mvollmary commented on May 31, 2024 2

I just released version 1.1.5 and 2.1.6 which contains a fix for this bug.

from spring-data.

christian-lechner avatar christian-lechner commented on May 31, 2024 1

@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.

christian-lechner avatar christian-lechner commented on May 31, 2024 1

Sets will be supported with the next release.

from spring-data.

christian-lechner avatar christian-lechner commented on May 31, 2024 1

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.

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.

bthj-tms avatar bthj-tms commented on May 31, 2024 1

Thanks for explaining how this works. That's what I meant by populated.

from spring-data.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

haqer1 avatar haqer1 commented on May 31, 2024

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.

nordgreg avatar nordgreg commented on May 31, 2024

@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.

christian-lechner avatar christian-lechner commented on May 31, 2024

@haqer1

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.

nordgreg avatar nordgreg commented on May 31, 2024

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.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

nordgreg avatar nordgreg commented on May 31, 2024

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.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

nordgreg avatar nordgreg commented on May 31, 2024

wow. thank you for doing that.

i'll try it out today.

from spring-data.

nordgreg avatar nordgreg commented on May 31, 2024

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.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

nordgreg avatar nordgreg commented on May 31, 2024

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.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

nordgreg avatar nordgreg commented on May 31, 2024

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.

christian-lechner avatar christian-lechner commented on May 31, 2024

@nordgreg do you have any further information for us about this issue?

from spring-data.

bthj-tms avatar bthj-tms commented on May 31, 2024

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.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

bthj-tms avatar bthj-tms commented on May 31, 2024

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 a List<Movie> attribute annotated with @Relations(...lazy=true)
  • Save each element in Actor's List<Movie> (where Movie has a List<Actor> attribute annotated with @Relations(...lazy=true))
  • Save an instance of Role for each Actor - 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.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

mvollmary avatar mvollmary commented on May 31, 2024

@christian-lechner thanks a lot
@bthj-tms @nordgreg I will release a new version asap

from spring-data.

christian-lechner avatar christian-lechner commented on May 31, 2024

@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.

christian-lechner avatar christian-lechner commented on May 31, 2024

@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.

christian-lechner avatar christian-lechner commented on May 31, 2024

@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.

mvollmary avatar mvollmary commented on May 31, 2024

@christian-lechner you can join our community slack

from spring-data.

bthj-tms avatar bthj-tms commented on May 31, 2024

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.

christian-lechner avatar christian-lechner commented on May 31, 2024

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.

bthj-tms avatar bthj-tms commented on May 31, 2024

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.

bthj-tms avatar bthj-tms commented on May 31, 2024

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.

mvollmary avatar mvollmary commented on May 31, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.