neo4j / neo4j-ogm

Java Object-Graph Mapping Library for Neo4j
https://neo4j.com/docs/ogm-manual/
Apache License 2.0
337 stars 165 forks source link

Play Framework 2.5 dynamic recompile - mapping failure #203

Closed frne closed 7 years ago

frne commented 8 years ago

The entity mapping fails on a dynamic recompile of SBT / Play Framework. When Play recompiles changed classes, the reflection fails.

When the application is being restarted, and therefore completely recompiled, everything works well.

Exception:

java.lang.IllegalArgumentException: Can not set java.lang.Long field ch.anypos.common.model.User.id to ch.anypos.common.model.User
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
    at java.lang.reflect.Field.get(Field.java:393)
    at org.neo4j.ogm.annotations.FieldWriter.read(FieldWriter.java:53)
    at org.neo4j.ogm.annotations.FieldReader.read(FieldReader.java:39)
    at org.neo4j.ogm.utils.EntityUtils.identity(EntityUtils.java:38)
    at org.neo4j.ogm.context.EntityGraphMapper.mapEntity(EntityGraphMapper.java:218)
    at org.neo4j.ogm.context.EntityGraphMapper.map(EntityGraphMapper.java:132)

Entity definition:

@NodeEntity
public class User extends Neo4jModel {

    @GraphId
    @Getter
    private Long id;

    @Getter
    @Setter
    private String salt;

    @Getter
    @Setter
    private String username;

    @Getter
    @Setter
    private String passwordHash;

    @Getter
    @Setter
    private String email;

    @Getter
    @Setter
    private boolean active;

    @Getter
    @Relationship(type = Relationships.WORKS_FOR, direction = Relationship.OUTGOING)
    private Organization organisation;
}

Additional Info:

The SessionFactory is injected into the data access objects via Guice. DAOs create a session from the injected SessionFactory like the following:

@Inject
public Neo4jCrudDao(SessionFactory sessionFactory) {
    this.session = sessionFactory.openSession();
}

Error ocures wheter the DAOs are bound dynamically or as eager singleton.

mangrish commented 8 years ago

I'm not really familiar with Play. Would this be the expected behaviour? A quick scan of JPA/Hibernate with Play shows that they seem to do a reload on touching. Could you confirm if this is what is required versus individual class reloading?

frne commented 8 years ago

I'm not really sure if it's a class loading issue. After reloading touched classes, Play restarts the app and entity mapping happens again (?). Getting the object identity (org.neo4j.ogm.utils.EntityUtils#identity) fails due to some reflection stuff which I didn't completely understand yet.

Additional info: This happens when any class is touched, even if it has nothing to do with the scanned entities.

Pulled a fork and trying to dig into it.

Edit: AFAIK it's expected behavior in Play, that touched classes are recompiled / reloaded.

frne commented 8 years ago

Disabling Play enhancer (which generates getter/setter methods for entities) does not solve the problem.

jasperblues commented 8 years ago

@frne Are you able to submit a sample project with a failing test case, or alternatively a test case that we can use in OGM? This would help us to address the issue quickly.

mangrish commented 7 years ago

@frne If you would like us to keep looking at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

joaocraveiro commented 7 years ago

I'm having this exact same problem. Any solutions for this?

joaocraveiro commented 7 years ago

@mangrish could you please reopen this? It is still happening and is a major setback in developing play framework applications with neo4j. I can provide a sample project but I think it's straight forward to reproduce what is happening here when you run the most basic play framework project with neo4j OGM - as soon as you change anything on your project and the server reloads automatically neo4j starts giving the error frne showed.

Dormmamu commented 7 years ago

Also having this issue with GWT - OGM - NEO4J application. I have the exact same error. I'm able to scan the model package to get my session, but when I wanna write something to Neo4j I get this error. I don't use @GraphId cause it's deprecated. I have an abstract class Entity with a Long field Id (no annotation) that others extend. @joaocraveiro Have you found an answer for this yet?

joaocraveiro commented 7 years ago

@Dormmamu after updating to the latest version of the ogm (3.0.1), neo4j (3.3) and of play framework (2.6.7) this is not happening to me anymore.