Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
09-28-2022 04:04 AM
@Node
public class User {
@Id
private String id;
private String username;
@Relationship("ACTIVE_BUSINESS_UNIT")
private BusinessUnit activeBusinessUnit;
}
@Node
public class BusinessUnit {
@Id
private String id;
private String name;
@Relationship(type = "BUSINESS_UNIT_IN", direction = OUTGOING)
private List<User> users = new ArrayList<>();
}
@Data
public class UserView {
private String id;
private String username;
private BusinessUnitView activeBusinessUnit;
@data
public static class BusinessUnitView {
private String id;
private String name;
}
}
UserView user = userRepository.findByUsername(myusername);
java.lang.ClassCastException: Cannot cast au.com.objects.neo4j.entity.BusinessUnit to au.com.objects.neo4j.entity.UserView$BusinessUnitView
Trying to use multilevel projections to control how much data gets loaded and am getting ClassCastException when I load from repository.
Any ideas what I'm doing wrong?
Solved! Go to Solution.
10-13-2022 01:36 AM
I am so sorry that I missed this question. This limitation is unfortunate but technical needed.
Basically what I would do is to use the interface projection to create an instance of the entity object from.
e.g something like:
class User {
User fromUserView(UserView userView) {
return new User(userView.getUsername(),...);
}
}
09-28-2022 04:27 AM
Appears multi level projections don't work for class based projections
"These DTO types can be used in exactly the same way projection interfaces are used, except that no proxying happens and no nested projections can be applied."
https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#projections.dtos
As only class based projections support doing updates, what is the preferred way to load a partial graph for update?
For example if I wanted to load a User and update it's activeBusinessUnit
UserView user = userRepository.findByUsername(myusername);
BusinessUnitView bu = businessUnitRepository.findById(myid);
user.setACtiveBusinessUnit(bu);
neo4jTemplate.save(User.class).one(user);
10-13-2022 01:36 AM
I am so sorry that I missed this question. This limitation is unfortunate but technical needed.
Basically what I would do is to use the interface projection to create an instance of the entity object from.
e.g something like:
class User {
User fromUserView(UserView userView) {
return new User(userView.getUsername(),...);
}
}
10-13-2022 09:42 PM
@gerrit_meier thanks for the reply, thats a great help.
So that seems to work, just needed to add @Version, is that expected?
This is what I ended up with. Now to try and apply similar to the rest of the migration too SDN6
IUserView userView = userRepository.findByUsername(username);
IBusinessUnitView bu = businessUnitRepository.findByName(name);
User user = new User(userView.getId(), userView.getVersion(),
userView.getUsername(),
new BusinessUnit(businessUnitView.getId(), businessUnitView.getVersion(),
businessUnitView.getName(),
null)); // users
neo4jTemplate.saveAs(user, IUserView.class);
10-14-2022 12:29 AM
The version annotation is needed regardless if you are using projection or not.
Otherwise, SDN does not know if the entity is new or already exists. It does not have any control over the identifier in your case and needs another information (the version) to determine if this was already processed or not.
I see a missing documentation piece around the identifiers and will take care of this.
All the sessions of the conference are now available online