Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
09-22-2019 06:38 AM
I have an entity with an array of rich relationships, like this:
@NodeEntity
public class User {
@Transient
private static final Logger log = LoggerFactory.getLogger(User.class);
@Id @GeneratedValue Long id;
@Relationship(type = "PLAYED")
public ArrayList<PlayRecord> played_josekis;
//...
I am finding that any query I do to load these User
entities gets played_josekis as null
if the User has no such relationships.
I have tried the built in findUserById
, and I have also tried a query like:
@Query("MATCH (u:User {user_id:{userId}})" +
"WITH u OPTIONAL MATCH (u) -[r:PLAYED]- (b:BoardPosition) " +
"RETURN u,r,b")
User loadUserWithPlayRecordByUserId(@Param("userId") Long user_id);
In the latter case, if the User has such a relationship, then the array is populated, but if they do not then it is null
instead of a zero sized array.
This seems reasonably painful - it means a check for null of this thing whenever a User is fetched, and adding an empty array when that's the case.
Am I missing something?
09-22-2019 08:11 AM
As far as I know, this is by design. The OGM has no contract to give you a zero-sized array in lieu of null. You could try assigning a zero-sized array in the constructor, as OGM sets values later in the object lifecycle, and I suspect it does not actually assign a null value.
09-22-2019 02:53 PM
Thanks for your quick answer!
At a meta level, I have to say "how does that make any sense"? If an entity has an array representing its relationships, how is it "helpful", or in what sense is it "natural" that returning "null" for "this entity definitely has no relationships"?
In fact, overall this one type of issue has been the single thing vexing my whole Neo project: trying to know/understand and ensure that my entities come back properly populated from queries.
But - if we take it as granted, then I think I can't do it in the constructor, because as I understand it I am obliged to have an empty constructor for OGM to use, aren't I? My entities all have this, because that's what I understood is required:
public User() {
// Empty constructor required as of Neo4j API 2.0.5
};
This kind of thing has lead to me starting to have "shims" between the Neo repository classes and the controllers that use them, where the manipulation to correctly populate the entities that get partially returned from Neo in various circumstances gets "fixed" so the controller doesn't have to be forever worrying whether the relationships are populated. It feels "wrong", so I'd love some insight on how this is intended or normally managed!
09-23-2019 09:28 AM
That's actually quite a standard approach, and exactly what I do. I have a view model for every entity model, and a converter class for converting between. This is so I can normalize or de-normalize for e.g. API request/response.
09-28-2019 07:37 AM
This is an interesting discussion. I struggled with this a bit, too. My solution was to initialize collections in the constructor and I don't think it's been a problem or causing a slowdown.
public User () {
this.played_josekis = new ArrayList();
}
09-28-2019 04:46 PM
Thanks for sharing that.
Somewhere along the lines I got the idea that I have to have an empty constructor, and that this is what Neo uses for constructing query response objects.
Is this simply mistaken on my part?
10-01-2019 01:41 PM
There needs to be a constructor that takes no arguments, but the constructor itself seems to not need to be empty, so long as any exceptions are checked (or values return null).
Actually, here it is in the documentation. A no-argument constructor is the only requirement.
https://neo4j.com/docs/ogm-manual/current/tutorial/#tutorial:annotations:noarg-constructor
All the sessions of the conference are now available online