Getting Null Pointer Exception Mongo Aggregation Using Spring Data(Dynamic Fields) - spring

This is my Mongo Pojo also getters and setters(Not added) .
#CompoundIndex(name = "account_date_idx", def = "{'account' : 1, 'date' : 1}", unique = true)
#Document(collection = "agent_data_storage")
public class AgentDataStorage extends MongoKeyedEntity<String> implements Serializable {
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
#Field
private Long account;
#Field()
private String date;
#Field
private Map<String, Double> dataPoints = new HashMap<>();
public AgentDataStorage() {
}
public AgentDataStorage(Long account) {
this.account = account;
this.date = dateFormat.format(new Date());
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(String account) {
this.account = Long.valueOf(account);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(Long account, Date date) {
this.account = account;
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(Long account, Date date, Map<String, Double> dataPoints) {
this.account = account;
this.date = dateFormat.format(date);
this.dataPoints = dataPoints;
}
public AgentDataStorage(Long account, String date, Map<String, Double> dataPoints) {
this.account = account;
this.date = date;
this.dataPoints = dataPoints;
}
public AgentDataStorage(String account, Date date) {
this.account = Long.valueOf(account);
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public AgentDataStorage(String account, String date) {
this.account = Long.valueOf(account);
this.date = date;
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0d);
}
}
public Long getAccount() {
return account;
}
public void setAccount(Long account) {
this.account = account;
}
public Date getDate() throws ParseException {
return dateFormat.parse(this.date);
}
public void setDate(Date date) {
this.date = dateFormat.format(date);
}
public Map<String, Double> getDataPoints() {
return dataPoints;
}
public void setDataPoints(Map<String, Double> dataPoints) {
this.dataPoints = dataPoints;
}
public void updateDataPoint(AgentDataPoints agentDataPoints, Double value) {
this.dataPoints.put(String.valueOf(agentDataPoints), value);
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("AgentDataStorage{");
sb.append("account=").append(account);
sb.append(", date=").append(date);
sb.append(", dataPoints=").append(dataPoints);
sb.append('}');
return sb.toString();
}
}
While Trying aggregation i am getting null Pointer Exception , Below is my Test Case.
#Test
public void aggregationTest() {
Long account = 12121l;
String startDay = "2016-01-01";
String endDay = "2016-01-03";
Aggregation aggregation = Aggregation
.newAggregation(match(Criteria.where("account").is(account).and("date")
.gte(startDay).lte(endDay)),
group("account").sum("dataPoints.TOTAL_BUS_COMMISSION").as("total"));
AggregationResults<AggregationResult> results = mongoTemplate.aggregate(aggregation,
AgentDataStorage.class, AggregationResult.class);
}
My AggregationResult class is -
public class AggregationResult {
private Long _id;
private Double total;
public Long get_id() {
return _id;
}
public void set_id(Long _id) {
this._id = _id;
}
public Double getTotal() {
return total;
}
public void setTotal(Double total) {
this.total = total;
}
}
Below is Stack Trace Of Error
java.lang.NullPointerException
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:233)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:214)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:210)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReferenceFor(TypeBasedAggregationOperationContext.java:96)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReference(TypeBasedAggregationOperationContext.java:91)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.getValue(GroupOperation.java:434)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.toDBObject(GroupOperation.java:416)
at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDBObject(GroupOperation.java:361)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:331)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1500)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1435)
at psl.service.core.agentanalytics.internal.AgentAnalyticsServiceTest.aggregationTest(AgentAnalyticsServiceTest.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
I also tried to debug the inside spring jar , It's throwing null for Double type inside AbstractMappingContext.java but not able to understant why it's happening .
The same mongo query is working in mongo console.
db.getCollection('agent_data_storage').aggregate([
{ "$match" : { "account" : 12121 , "date" : { "$gte" : "2016-01-01" , "$lte" : "2016-01-03"}}}
, { "$group" : { "_id" : "$account" , "total" : { "$sum" : "$dataPoints.TOTAL_BUS_COMMISSION"}}}])
the result for the above query is
{
"_id" : NumberLong(12121),
"total" : 402.0
}
Thanks for any kind of Help .
Sample Doc from AgentDataStorage-
{
"_id" : ObjectId("586233e3fb94f6f5640196cf"),
"account" : NumberLong(12121),
"date" : "2016-01-01",
"dataPoints" : {
"TOTAL_BUS_COMMISSION" : 0.0
}
}

Don't use the typed aggregation variant of aggregation which is essentially trying to translate property references in the input type (AgentDataStorage) into field names and fails when it doesn't find the property references, in your case dataPoints.TOTAL_BUS_COMMISSION.
Use
AggregationResults<AggregationResult> results = mongoTemplate.aggregate(aggregation,
"agent_data_storage", AggregationResult.class);

Related

hibernate/Spring/Jpa #oneToMany cascade update

I'm trying to add in the decorator cascade = CascadeType.ALL on the field one to many of my version modele in spring in order to update every hyper parameter when i update my version.Like you can see below.
#Entity
#Table(name = "version")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Version implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "num", nullable = false)
private Integer num;
#Column(name = "creation_date")
private ZonedDateTime creationDate;
#Column(name = "execution_date")
private ZonedDateTime executionDate;
#Column(name = "weights_uri")
private String weightsURI;
#OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true)
#JsonIgnoreProperties({"version", "metricsType"})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<ResultExecution> resultExecutions = new HashSet<>();
#OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
#JsonIgnoreProperties({"version"})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<HyperParameter> hyperParameters = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getNum() {
return num;
}
public Version num(Integer num) {
this.num = num;
return this;
}
public void setNum(Integer num) {
this.num = num;
}
public ZonedDateTime getCreationDate() {
return creationDate;
}
public Version creationDate(ZonedDateTime creationDate) {
this.creationDate = creationDate;
return this;
}
public void setCreationDate(ZonedDateTime creationDate) {
this.creationDate = creationDate;
}
public ZonedDateTime getExecutionDate() {
return executionDate;
}
public Version executionDate(ZonedDateTime executionDate) {
this.executionDate = executionDate;
return this;
}
public void setExecutionDate(ZonedDateTime executionDate) {
this.executionDate = executionDate;
}
public String getWeightsURI() {
return weightsURI;
}
public Version weightsURI(String weightsURI) {
this.weightsURI = weightsURI;
return this;
}
public void setWeightsURI(String weightsURI) {
this.weightsURI = weightsURI;
}
public Set<ResultExecution> getResultExecutions() {
return resultExecutions;
}
public Version resultExecutions(Set<ResultExecution> resultExecutions) {
this.resultExecutions = resultExecutions;
return this;
}
public Version addResultExecution(ResultExecution resultExecution) {
this.resultExecutions.add(resultExecution);
resultExecution.setVersion(this);
return this;
}
public Version removeResultExecution(ResultExecution resultExecution) {
this.resultExecutions.remove(resultExecution);
resultExecution.setVersion(null);
return this;
}
public void setResultExecutions(Set<ResultExecution> resultExecutions) {
this.resultExecutions = resultExecutions;
}
public Set<HyperParameter> getHyperParameters() {
return hyperParameters;
}
public Version hyperParameters(Set<HyperParameter> hyperParameters) {
this.hyperParameters = hyperParameters;
return this;
}
public Version addHyperParameter(HyperParameter hyperParameter) {
this.hyperParameters.add(hyperParameter);
hyperParameter.setVersion(this);
return this;
}
public Version removeHyperParameter(HyperParameter hyperParameter) {
this.hyperParameters.remove(hyperParameter);
hyperParameter.setVersion(null);
return this;
}
public void setHyperParameters(Set<HyperParameter> hyperParameters) {
this.hyperParameters = hyperParameters;
}
public Set<Data> getData() {
return data;
}
public Version data(Set<Data> data) {
this.data = data;
return this;
}
public Version addData(Data data) {
this.data.add(data);
data.getVersions().add(this);
return this;
}
public Version removeData(Data data) {
this.data.remove(data);
data.getVersions().remove(this);
return this;
}
public void setData(Set<Data> data) {
this.data = data;
}
public ModelConfiguration getModelConfiguration() {
return modelConfiguration;
}
public Version modelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
return this;
}
public void setModelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
}
// jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Version version = (Version) o;
if (version.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), version.getId());
}
#Override
public int hashCode() {
return Objects.hashCode(getId());
}
#Override
public String toString() {
return "Version{" +
"id=" + getId() +
", num='" + getNum() + "'" +
", creationDate='" + getCreationDate() + "'" +
", executionDate='" + getExecutionDate() + "'" +
", weightsURI='" + getWeightsURI() + "'" +
"}";
}
}
My hyperParameter model looks like this :
#Entity
#Table(name = "hyper_parameter")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class HyperParameter implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "parameter_value", nullable = false)
private String parameterValue;
#ManyToOne(optional = false)
#NotNull
#JsonIgnoreProperties({"resultExecutions", "hyperParameters", "data", "modelConfiguration"})
private Version version;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getParameterValue() {
return parameterValue;
}
public HyperParameter parameterValue(String parameterValue) {
this.parameterValue = parameterValue;
return this;
}
public void setParameterValue(String parameterValue) {
this.parameterValue = parameterValue;
}
public Version getVersion() {
return version;
}
public HyperParameter version(Version version) {
this.version = version;
return this;
}
public void setVersion(Version version) {
this.version = version;
}
public HyperParameterType getHyperParameterType() {
return hyperParameterType;
}
public HyperParameter hyperParameterType(HyperParameterType hyperParameterType) {
this.hyperParameterType = hyperParameterType;
return this;
}
public void setHyperParameterType(HyperParameterType hyperParameterType) {
this.hyperParameterType = hyperParameterType;
}
// jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HyperParameter hyperParameter = (HyperParameter) o;
if (hyperParameter.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), hyperParameter.getId());
}
#Override
public int hashCode() {
return Objects.hashCode(getId());
}
#Override
public String toString() {
return "HyperParameter{" +
"id=" + getId() +
", parameterValue='" + getParameterValue() + "'" +
"}";
}
}
I update a json and try a put with it .I change the value of the field parametervalue from 2 to 3 .
{
"id": 1,
"num": 1,
"creationDate": "2017-05-11T00:00:00+02:00",
"executionDate": null,
"weightsURI": "tests/scripts/sequential/weights/weights_le_net_5.h5py",
"resultExecutions": [
{
"id": 1,
"metricValues": "",
"executionType": "TRAIN",
"numPrediction": null
},
{
"id": 2,
"metricValues": "",
"executionType": "TRAIN",
"numPrediction": null
}
],
"hyperParameters": [
{
"id": 1,
"parameterValue": "2",
"hyperParameterType": {
"id": 1,
"name": "epochs",
"parameterType": "INTEGER",
"parameterDefaultValue": "0",
"isRequired": true
}
},
{
"id": 2,
"parameterValue": "32",
"hyperParameterType": {
"id": 2,
"name": "batch_size",
"parameterType": "INTEGER",
"parameterDefaultValue": "32",
"isRequired": true
}
}
],
"modelConfiguration": {
"id": 1,
"name": "Modele LeNet5",
"creationDate": "2017-05-11T00:00:00+02:00",
"updateDate": "2017-05-11T00:00:00+02:00",
"saveURI": "tests/scripts/sequential/models/le_net_5.json"
}
}
But when i do i got a 500 internal serveur error and stack trace like the one bellow about a null constraint violation.
<!-- What do you expect the result to be? -->
<!-- What is the actual result you get? (Please include any errors.) -->
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
[1:59]
t org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:75)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:71)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 153 common frames omitted
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.saagie.picsaagie2017_frontend.domain.HyperParameter] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='can not be null ', propertyPath=version, rootBeanClass=class com.saagie.picsaagie2017_frontend.domain.HyperParameter, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
How can i update my hyperParameters when i update my version whitout getting this error.
Use the #PreUpdate and #PrePersist callbacks in the HyperParameter class like so:
#PreUpdate
#PrePersist
public void setChildObjects() {
if (getVersions() != null)
{
for (Version version : getVersions())
{
version.setHyperParameters (this);
}
}
}
Refer to this for more information : http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html#tutorial-associations-usingbidir
Both solution actually work i had a second error because of what is discussed in that topic : Spring data rest one to many cascade all . I just had to add #JsonManagedReference and #JsonBackReference because i had marshalling problem on the reference of version when i tried to update my HyperParameters in cascade.
You just have validation error. You try to put interpolatedMessage with null value. Ok but first remove #NotNull annotation on this field.

how can get the last inserted value in spring mongodb?

i have a class Named Device
#Document
public class Devise
{
#Id
public String id;
public String reference;
#DBRef
public List<Mesures> listMes;
public Devise() {
// TODO Auto-generated constructor stub
}
public Devise(String reference, List<Mesures> listMes) {
super();
this.reference = reference;
this.listMes = listMes;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public List<Mesures> getListMes() {
return listMes;
}
public void setListMes(List<Mesures> listMes) {
this.listMes = listMes;
}
}
another class named Mesures
#Document
public class Mesures {
#Id
private String id;
private Double value;
private Date date;
#DBRef
private Devise devise;
public Mesures() {
// TODO Auto-generated constructor stub
}
public Mesures(Double value, Date date, Devise devise) {
super();
this.value = value;
this.date = date;
this.devise = devise;
}
public Mesures(Double value, Date date) {
super();
this.value = value;
this.date = date;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Double getValue() {
return value;
}
public void setValue(Double value) {
this.value = value;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Devise getDevise() {
return devise;
}
public void setDevise(Devise devise) {
this.devise = devise;
}
and this is the MesuresRepository who extend from Mongo Repository
public interface MesureRepository extends MongoRepository<Mesures, String>{
public Mesures findTopByDeviseOrderByDateDesc(String DeviseId);
}
and this is the main app (Spring boot app)
ApplicationContext ctx = SpringApplication.run(UiApplication.class, args);
MesureDAO MDAO = ctx.getBean(MesureDAO.class);
DeviceDAO DDAO = ctx.getBean(DeviceDAO.class);
DateFormat df = new SimpleDateFormat("yyyy-mm-dd-hh-mm-ss");
Mesures m1 = new Mesures(10.0, df.parse("2016-11-12-12-51-42"));
Mesures m2 = new Mesures(15.2,df.parse("2016-11-12-12-52-42"));
//add Mesure
MDAO.addMesure(m1);
MDAO.addMesure(m2);
List<Mesures>listMes = new ArrayList<>();
listMes.add(m1);
listMes.add(m2);
//add Device
Devise D = new Devise("G2fgG123", listMes);
DDAO.addDevice(D);
and the database look like :
db.devise.find().pretty()
{
"_id" : ObjectId("58bc8218d980530898a0b047"),
"_class" : "demo.model.Devise",
"reference" : "G2fgG123",
"listMes" : [
DBRef("mesures", ObjectId("58bc8218d980530898a0b045")),
DBRef("mesures", ObjectId("58bc8218d980530898a0b046"))
]
}
and the restController like this
#RestController
public class MesuressController {
#Autowired
MesureRepository mesureRepo;
#RequestMapping(value = "/mesure/{DeviseId}")
public Mesures findByDeviseIdOrderByDate(#PathVariable("DeviseId")String DeviseId) {
return mesureRepo.findTopByDeviseIdOrderByDateDesc(DeviseId);
}}
and this is the measure Doc
db.mesures.find().pretty()
{
"_id" : ObjectId("58bc8218d980530898a0b045"),
"_class" : "demo.model.Mesures",
"value" : 10,
"date" : ISODate("2016-01-11T23:51:42Z")
}
{
"_id" : ObjectId("58bc8218d980530898a0b046"),
"_class" : "demo.model.Mesures",
"value" : 15.2,
"date" : ISODate("2016-01-11T23:52:42Z")
}
and this the device document after changing
db.devise.find().pretty()
{
"_id" : ObjectId("58bd306500ff6d1670916a7d"),
"_class" : "demo.model.Devise",
"reference" : "G2fgG123",
"listMes" : [
{
"_id" : ObjectId("58bd306500ff6d1670916a7b"),
"value" : 10,
"date" : ISODate("2016-01-11T23:51:42Z")
},
{
"_id" : ObjectId("58bd306500ff6d1670916a7c"),
"value" : 15.2,
"date" : ISODate("2016-01-11T23:52:42Z")
}
]
Try to use mongodb's $natural operator:
Query query = new Query().with(new Sort(Direction.ASC, "$natural"));
BasicQuery basicQuery = new BasicQuery(new BasicDBObject());
basicQuery.setSortObject(new BasicDBObject("$natural", -1));

How to Use Mongo Pojos in Bulk Upsert

Hi i have a list of Mongo Pojo I want to use upsert .I don't know how to use My pojo's .
#Test
public void testAgentDataStorage() {
AgentDataStorage a = new AgentDataStorage(124l);
DBCollection collection = mongoTemplate.getDb().getCollection("agent_data_storage");
BulkWriteOperation bulkWriteOperation = collection.initializeUnorderedBulkOperation();
BulkWriteRequestBuilder bulkWriteRequestBuilder = bulkWriteOperation.find((DBObject) a);
BulkUpdateRequestBuilder updateReq = bulkWriteRequestBuilder.upsert();
a.getDataPoints().put("TOTAL_INCENTIVE_EARNINGS" , 13);
updateReq.replaceOne((DBObject) a);
BulkWriteResult result = bulkWriteOperation.execute();
}
Here AgentDataStorage is my pojo and this code is giving error
AgentDataStorage cannot be cast to com.mongodb.DBObject .
Below is my AgentDataStorage
#CompoundIndex(name = "account_date_idx", def = "{'account' : 1, 'date' : 1}", unique = true)
#Document(collection = "agent_data_storage")
public class AgentDataStorage extends MongoKeyedEntity<String> implements Serializable {
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
#Field
private Long account;
#Field()
private String date;
#Field
private Map<String, Integer> dataPoints = new HashMap<>();
public AgentDataStorage(Long account) {
this.account = account;
this.date = dateFormat.format(new Date());
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(String account) {
this.account = Long.valueOf(account);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(Long account, Date date) {
this.account = account;
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(Long account, Date date, Map<String, Integer> dataPoints) {
this.account = account;
this.date = dateFormat.format(date);
this.dataPoints = dataPoints;
}
public AgentDataStorage(String account, Date date) {
this.account = Long.valueOf(account);
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(String account, String date) {
this.account = Long.valueOf(account);
this.date = date;
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public Long getAccount() {
return account;
}
public void setAccount(Long account) {
this.account = account;
}
public Date getDate() throws ParseException {
return dateFormat.parse(this.date);
}
public void setDate(Date date) {
this.date = dateFormat.format(date);
}
public Map<String, Integer> getDataPoints() {
return dataPoints;
}
public void setDataPoints(Map<String, Integer> dataPoints) {
this.dataPoints = dataPoints;
}
public void updateDataPoint(AgentDataPoints agentDataPoints, Integer value) {
this.dataPoints.put(String.valueOf(agentDataPoints), value);
}
Mongo Java Driver doesn't have support for complex types and it looks like your pojos are annotated with spring mongo db annotation.
You've couple of options here MongoTemplate and MongoRepository.
MongoTemplate: http://docs.spring.io/spring-data/data-mongo/docs/1.10.0.M1/reference/html/#mongo-template
MongoRepository: http://docs.spring.io/spring-data/data-mongo/docs/1.10.0.M1/reference/html/#mongo.repositories

Not-null property references a transient value - transient instance must be saved before current operation

This is the log exception:
GRAVE: Servlet.service() for servlet [dispatcher] in context with path [/Libreria] threw exception [Request processing failed; nested exception is org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.angelo.springmvc.model.PrestitoLibro.prestito -> com.angelo.springmvc.model.Prestito] with root cause
org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.angelo.springmvc.model.PrestitoLibro.prestito -> com.angelo.springmvc.model.Prestito
at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:137)
at org.hibernate.engine.spi.ActionQueue.checkNoUnresolvedActionsAfterOperation(ActionQueue.java:318)
at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsAfterOperation(SessionImpl.java:658)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:813)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at com.angelo.springmvc.dao.AbstractDao.persist(AbstractDao.java:34)
at com.angelo.springmvc.dao.PrestitoLibroDaoImpl.savePrestitoLibro(PrestitoLibroDaoImpl.java:27)
at com.angelo.springmvc.service.PrestitoServiceImpl.salvaPrestito(PrestitoServiceImpl.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy45.salvaPrestito(Unknown Source)
at com.angelo.springmvc.controller.ShoppingCartController.ordinaShoppingCart(ShoppingCartController.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
The scenario is the following: I have two entity beans Prestito and PrestitoLibro, a ServicePrestito and a session bean ShoppingCard with a Controller:
#Entity
#Table(name="PRESTITO")
#XmlRootElement
public class Prestito {
private Integer id;
private Cliente cliente;
private Date dataprestito;
private Set<PrestitoLibro> prestitolibros = new HashSet<PrestitoLibro>(0);
public Prestito() {
}
public Prestito(Cliente cliente, Date dataprestito) {
this.cliente = cliente;
this.dataprestito = dataprestito;
}
public Prestito(Cliente cliente, Date dataprestito, Set<PrestitoLibro> prestitolibros) {
this.cliente = cliente;
this.dataprestito = dataprestito;
this.prestitolibros = prestitolibros;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_cliente", nullable = false)
public Cliente getCliente() {
return this.cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
#Temporal(TemporalType.DATE)
#Column(name = "dataprestito", nullable = false, length = 10)
public Date getDataprestito() {
return this.dataprestito;
}
public void setDataprestito(Date dataprestito) {
this.dataprestito = dataprestito;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "prestito")
public Set<PrestitoLibro> getPrestitolibros() {
return this.prestitolibros;
}
public void setPrestitolibros(Set<PrestitoLibro> prestitolibros) {
this.prestitolibros = prestitolibros;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Prestito other = (Prestito) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
#Override
public String toString() {
return "Prestito [id=" + id + ", cliente=" + cliente + ", dataprestito=" + dataprestito
+ ", prestitolibros=" + prestitolibros + "]";
}
}
#Entity
#Table(name="PRESTITOLIBRO")
#XmlRootElement
public class PrestitoLibro {
private Integer id;
private Libro libro;
private Prestito prestito;
private Integer qta;
private Double subtotal;
public PrestitoLibro() {
}
public PrestitoLibro(Libro libro, Prestito prestito) {
this.libro = libro;
this.prestito = prestito;
}
public PrestitoLibro(Libro libro, Prestito prestito, Integer qta, Double subtotal) {
this.libro = libro;
this.prestito = prestito;
this.qta = qta;
this.subtotal = subtotal;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)//, cascade=CascadeType.ALL
#JoinColumn(name = "id_libro", nullable = false)
public Libro getLibro() {
return this.libro;
}
public void setLibro(Libro libro) {
this.libro = libro;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_prestito", nullable = false)
public Prestito getPrestito() {
return this.prestito;
}
public void setPrestito(Prestito prestito) {
this.prestito = prestito;
}
#Column(name = "qta")
public Integer getQta() {
return this.qta;
}
public void setQta(Integer qta) {
this.qta = qta;
}
#Column(name = "subtotal", precision = 22, scale = 0)
public Double getSubtotal() {
return this.subtotal;
}
public void setSubtotal(Double subtotal) {
this.subtotal = subtotal;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PrestitoLibro other = (PrestitoLibro) obj;
if (id != other.id)
return false;
return true;
}
#Override
public String toString() {
return "PrestitoLibro [id=" + id + ", libro=" + libro + ", prestito=" + prestito + ", qta=" + qta
+ ", subtotal=" + subtotal + "]";
}
}
#Component
#Scope(value=WebApplicationContext.SCOPE_SESSION,
proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ShoppingCart {
private Map<Libro, Integer> contents = new HashMap<>();
public Map<Libro, Integer> getContents() {
return contents;
}
public void setContents(Map<Libro, Integer> contents) {
this.contents = contents;
}
public void addLibro(Libro libro, int count){
if(contents.containsKey(libro)){
contents.put(libro, contents.get(libro)+count);
}else{
contents.put(libro,count);
}
}
public void removeLibro(Libro libro){
contents.remove(libro);
}
public void clearCart(){
contents.clear();
}
#Override
public String toString() {
return "ShoppingCart [contents=" + contents + "]";
}
public double getTotalCost(){
double totalcost = 0;
int i = 0;
for(Libro libro: contents.keySet()){
i = contents.get(libro);
totalcost += i * libro.getPrezzo();
}
return totalcost;
}
}
The problem occurs when I call salvaprestito() here:
#Service("prestitoService")
#Transactional
public class PrestitoServiceImpl implements PrestitoService {
#Autowired
private PrestitoDao dao;
#Autowired
private PrestitoLibroDao daoprestitolibro;
public Prestito findById(int id) {
return dao.findById(id);
}
public void savePrestito(Prestito prestito) {
dao.savePrestito(prestito);
}
public void updatePrestito(Prestito prestito) {
Prestito entity = dao.findById(prestito.getId());
if(entity!=null){
entity.setCliente(prestito.getCliente());
entity.setDataprestito(prestito.getDataprestito());
entity.setPrestitolibros(prestito.getPrestitolibros());
}
}
public void deletePrestitoBySss(String sss) {
dao.deletePrestitoBySss(sss);
}
public List<Prestito> findAllPrestiti() {
return dao.findAllPrestiti();
}
public Prestito findPrestitoBySss(String sss) {
return dao.findPrestitoBySss(sss);
}
public boolean isPrestitoSssUnique(Integer id, String sss) {
Prestito prestito = findPrestitoBySss(sss);
return ( prestito == null || ((id != null) && (prestito.getId() == id)));
}
public void salvaPrestito(Map<Libro, Integer> shoppingcartContents, Cliente cliente){
Prestito prestito = new Prestito();
prestito = dao.findById(prestito.getId());
prestito.setCliente(cliente);
dao.savePrestito(prestito);
for(Entry<Libro, Integer> entry: shoppingcartContents.entrySet()){
PrestitoLibro prestLibro = new PrestitoLibro(entry.getKey(),prestito);
prestLibro.setQta(entry.getValue());
prestLibro.setPrestito(prestito); prestLibro.setSubtotal(entry.getKey().getPrezzo()*entry.getValue());
daoprestitolibro.savePrestitoLibro(prestLibro);
prestito.getPrestitolibros().add(prestLibro);
}
}
And this is the Shopping Cart Controller:
#Controller
public class ShoppingCartController {
private static final Logger logger = LoggerFactory.getLogger(ShoppingCartController.class);
#Autowired
private LibroService libroservice;
#Autowired
private PrestitoService prestitoservice;
#Autowired
private ShoppingCart shoppingcart;
#RequestMapping(value = { "/shoppingcart/add/{libroId}" }, method = RequestMethod.GET)
public String addtoShoppingCart(#PathVariable("libroId") int libroId, #RequestHeader("referer") String rForm) {
Libro libro = (Libro) libroservice.findById(libroId);
shoppingcart.addLibro(libro, 1);
logger.debug("Aggiunto Libro a carrello" + libro);
return "redirect:" + rForm;
}
#RequestMapping(value = { "/shoppingcart" }, method = RequestMethod.GET)
public String viewShoppingCart(Model model) {
model.addAttribute("shoppingcart", shoppingcart);
return "shoppingcart";
}
#RequestMapping(value = { "/shoppingcart/order" }, method = RequestMethod.POST)
public String ordinaShoppingCart(HttpSession session) {
if(shoppingcart.getContents().isEmpty()){
return "redirect:/shoppingcart";
}else{
Cliente cliente = (Cliente) session.getAttribute("cliente");
prestitoservice.salvaPrestito(shoppingcart.getContents(), cliente);
return "redirect:/shoppingcart";
}
}
These are the Daos:
#Repository("prestitolibroDao")
public class PrestitoLibroDaoImpl extends AbstractDao<Integer, PrestitoLibro> implements PrestitoLibroDao{
public PrestitoLibro findById(int id) {
PrestitoLibro prestitolibro = getByKey(id);
if(prestitolibro!=null){
Hibernate.initialize(prestitolibro.getId());
}
return prestitolibro;
}
public void savePrestitoLibro(PrestitoLibro prestitolibro) {
persist(prestitolibro);
}
public void deletePrestitoLibroById(int id) {
Query query = getSession().createSQLQuery("delete from Prestitolibro where id = :id");
query.setString("id",(String) Integer.toString(id));
query.executeUpdate();
}
#SuppressWarnings("unchecked")
public List<PrestitoLibro> findAllPrestitiLibro() {
Criteria criteria = createEntityCriteria();
return (List<PrestitoLibro>) criteria.list();
}
#SuppressWarnings("unchecked")
public List<PrestitoLibro> findAllPrestitiLibroByPrestito(int prestitoId) {
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.eq("id_prestito", prestitoId));
return (List<PrestitoLibro>) criteria.list();
}
#SuppressWarnings("unchecked")
public List<PrestitoLibro> findAllPrestitiLibroByLibro(int libroId) {
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.eq("id_libro", libroId));
return (List<PrestitoLibro>) criteria.list();
}
#Repository("prestitoDao")
public class PrestitoDaoImpl extends AbstractDao<Integer, Prestito> implements PrestitoDao{
public Prestito findById(int id) {
Prestito prestito = getByKey(id);
if(prestito!=null){
Hibernate.initialize(prestito.getId());
}
return prestito;
}
public void savePrestito(Prestito prestito) {
persist(prestito);
// Save prestito significa salvare il prestito o/e anche PrestitoLibiri
}
public void deletePrestitoBySss(String sss) {
Query query = getSession().createSQLQuery("delete from Libro where snn = :snn");
query.setString("sss", sss);
query.executeUpdate();
}
#SuppressWarnings("unchecked")
public List<Prestito> findAllPrestiti() {
Criteria criteria = createEntityCriteria();
return (List<Prestito>) criteria.list();
}
public Prestito findPrestitoBySss(String sss) {
System.out.println("SSS : "+sss);
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.eq("sss", sss));
Prestito prestito = (Prestito)criteria.uniqueResult();
if(prestito!=null){
Hibernate.initialize(prestito.getId());
}
return prestito;
}
Hibernate needs only id in Prestito to associate it with PrestitoLibro by a foreign key. I think, you don't have id in prestito here
prestLibro.setPrestito(prestito);
daoprestitolibro.savePrestitoLibro(prestLibro);
Try to output prestito.getId() before set it to prestLibro.
If you really don't have id the reason may be with this generation strategy
#GeneratedValue(strategy = IDENTITY)
or you don't have a transaction with #Transactional in the PrestitoServiceImpl so dao.savePrestito(prestito) doesn't save prestito at all. May be adding of your spring xml configuration in your question let to help you.
You do some unnecessary stuff in your method so it should be
public void salvaPrestito(Map<Libro, Integer> shoppingcartContents, Cliente cliente){
Prestito prestito = new Prestito();
prestito.setCliente(cliente);
dao.savePrestito(prestito);
for(Entry<Libro, Integer> entry: shoppingcartContents.entrySet()){
PrestitoLibro prestLibro = new PrestitoLibro(entry.getKey(), prestito);
prestLibro.setQta(entry.getValue());
prestLibro.setSubtotal(entry.getKey().getPrezzo() * entry.getValue());
daoprestitolibro.savePrestitoLibro(prestLibro);
}
}
You don't need prestLibro.setPrestito(prestito) and
prestito.getPrestitolibros().add(prestLibro).

spring data neo4j ,i can't solve it

I use spring data neo4j,i have user.class.movie.class,rating.class,i create relationship between movie and rating,when i run the programer,i can get the rating(star,comment)but cannot get the movie's title(null)
movie.class
package com.oberon.fm.domain;
#NodeEntity
public class Movie {
#GraphId
Long nodeId;
#Indexed(indexType = IndexType.FULLTEXT, indexName = "id")
String id;
#Indexed(indexType = IndexType.FULLTEXT, indexName = "search", numeric = false)
String title;
String description;
#RelatedTo(type = "DIRECTED", direction = INCOMING)
Person director;
#RelatedTo(type = "ACTS_IN", direction = INCOMING)
Set<Person> actors;
#RelatedToVia(elementClass = Role.class, type = "ACTS_IN", direction = INCOMING)
// Iterable<Role> roles;
Set<Role> roles = new HashSet<>();
#RelatedToVia(elementClass = Rating.class, type = "RATED", direction = INCOMING)
#Fetch
Iterable<Rating> ratings;
// Set<Rating> ratings = new HashSet<>();
private String language;
private String imdbId;
private String tagline;
private Date releaseDate;
private Integer runtime;
private String homepage;
private String trailer;
private String genre;
private String studio;
private Integer version;
private Date lastModified;
private String imageUrl;
public Movie() {
}
public Long getNodeId() {
return nodeId;
}
public void setNodeId(Long nodeId) {
this.nodeId = nodeId;
}
public Movie(String id, String title) {
this.id = id;
this.title = title;
}
public Collection<Person> getActors() {
return actors;
}
public Collection<Role> getRoles() {
return IteratorUtil.asCollection(roles);
}
public int getYear() {
if (releaseDate == null)
return 0;
Calendar cal = Calendar.getInstance();
cal.setTime(releaseDate);
return cal.get(Calendar.YEAR);
}
public String getId() {
return id;
}
public String getTitle() {
return title;
}
#Override
public String toString() {
return String.format("%s (%s) [%s]", title, releaseDate, id);
}
public String getDescription() {
return description;
}
public int getStars() {
Iterable<Rating> allRatings = ratings;
if (allRatings == null)
return 0;
int stars = 0, count = 0;
for (Rating rating : allRatings) {
stars += rating.getStars();
count++;
}
return count == 0 ? 0 : stars / count;
}
public Collection<Rating> getRatings() {
Iterable<Rating> allRatings = ratings;
return allRatings == null ? Collections.<Rating> emptyList()
: IteratorUtil.asCollection(allRatings);
}
/*
* public Set<Rating> getRatings() { return ratings; }
*/
public void setRatings(Set<Rating> ratings) {
this.ratings = ratings;
}
/*
* public void addRating(Rating rating) { ratings.add(rating); }
*/
public void setTitle(String title) {
this.title = title;
}
public void setLanguage(String language) {
this.language = language;
}
public void setImdbId(String imdbId) {
this.imdbId = imdbId;
}
public void setTagline(String tagline) {
this.tagline = tagline;
}
public void setDescription(String description) {
this.description = description;
}
public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}
public void setRuntime(Integer runtime) {
this.runtime = runtime;
}
public void setHomepage(String homepage) {
this.homepage = homepage;
}
public void setTrailer(String trailer) {
this.trailer = trailer;
}
public void setGenre(String genre) {
this.genre = genre;
}
public void setStudio(String studio) {
this.studio = studio;
}
public void setVersion(Integer version) {
this.version = version;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getLanguage() {
return language;
}
public String getImdbId() {
return imdbId;
}
public String getTagline() {
return tagline;
}
public Date getReleaseDate() {
return releaseDate;
}
public Integer getRuntime() {
return runtime;
}
public String getHomepage() {
return homepage;
}
public String getTrailer() {
return trailer;
}
public String getGenre() {
return genre;
}
public String getStudio() {
return studio;
}
public Integer getVersion() {
return version;
}
public Date getLastModified() {
return lastModified;
}
public String getImageUrl() {
return imageUrl;
}
public String getYoutubeId() {
String trailerUrl = trailer;
if (trailerUrl == null || !trailerUrl.contains("youtu"))
return null;
String[] parts = trailerUrl.split("[=/]");
int numberOfParts = parts.length;
return numberOfParts > 0 ? parts[numberOfParts - 1] : null;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Movie movie = (Movie) o;
if (nodeId == null)
return super.equals(o);
return nodeId.equals(movie.nodeId);
}
#Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
public Person getDirector() {
return director;
}
}
user.class
package com.oberon.fm.domain;
#NodeEntity
public class User {
#GraphId
Long nodeId;
public static final String SALT = "cewuiqwzie";
public static final String FRIEND = "FRIEND";
public static final String RATED = "RATED";
#Indexed(indexType = IndexType.FULLTEXT, indexName = "login")
String login;
#Indexed
String name;
String password;
public void setPassword(String password) {
this.password = password;
}
String info;
private Roles[] roles;
public User() {
}
public User(String login, String name, String password, Roles... roles) {
this.login = login;
this.name = name;
this.password = encode(password);
this.roles = roles;
}
private String encode(String password) {
return new Md5PasswordEncoder().encodePassword(password, SALT);
}
#RelatedToVia(type = RATED)
#Fetch
Iterable<Rating> ratings;
// Set<Rating> ratings = new HashSet<>();
#RelatedTo(type = RATED)
Set<Movie> favorites;
public Set<Movie> getFavorites() {
return favorites;
}
public void setFavorites(Set<Movie> favorites) {
this.favorites = favorites;
}
#RelatedTo(type = FRIEND, direction = Direction.BOTH)
#Fetch
Set<User> friends;
public void addFriend(User friend) {
this.friends.add(friend);
}
public Rating rate(Neo4jOperations template, Movie movie, int stars,
String comment) {
final Rating rating = template.createRelationshipBetween(this, movie,
Rating.class, RATED, false).rate(stars, comment);
return template.save(rating);
}
/*
* public Rating rate(Movie movie, int stars, String comment) { if (ratings
* == null) { ratings = new HashSet<>(); }
*
* Rating rating = new Rating(this, movie, stars, comment);
* ratings.add(rating); movie.addRating(rating); return rating; }
*/
public Collection<Rating> getRatings() {
return IteratorUtil.asCollection(ratings);
}
/*
* public Set<Rating> getRatings() { return ratings; }
*/
#Override
public String toString() {
return String.format("%s (%s)", name, login);
}
public String getName() {
return name;
}
public Set<User> getFriends() {
return friends;
}
public Roles[] getRole() {
return roles;
}
public String getLogin() {
return login;
}
public String getPassword() {
return password;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public void updatePassword(String old, String newPass1, String newPass2) {
if (!password.equals(encode(old)))
throw new IllegalArgumentException("Existing Password invalid");
if (!newPass1.equals(newPass2))
throw new IllegalArgumentException("New Passwords don't match");
this.password = encode(newPass1);
}
public void setName(String name) {
this.name = name;
}
public boolean isFriend(User other) {
return other != null && getFriends().contains(other);
}
public enum Roles implements GrantedAuthority {
ROLE_USER, ROLE_ADMIN;
#Override
public String getAuthority() {
return name();
}
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
User user = (User) o;
if (nodeId == null)
return super.equals(o);
return nodeId.equals(user.nodeId);
}
public Long getId() {
return nodeId;
}
#Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : super.hashCode();
}
}
rating.class
package com.oberon.fm.domain;
#RelationshipEntity
public class Rating {
private static final int MAX_STARS = 5;
private static final int MIN_STARS = 0;
#GraphId
Long id;
#StartNode
User user;
#EndNode
Movie movie;
int stars;
String comment;
public User getUser() {
return user;
}
public Movie getMovie() {
return movie;
}
public int getStars() {
return stars;
}
public void setStars(int stars) {
this.stars = stars;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Rating rate(int stars, String comment) {
if (stars >= MIN_STARS && stars <= MAX_STARS)
this.stars = stars;
if (comment != null && !comment.isEmpty())
this.comment = comment;
return this;
}
public Rating() {
}
public void setUser(User user) {
this.user = user;
}
public void setMovie(Movie movie) {
this.movie = movie;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Rating rating = (Rating) o;
if (id == null)
return super.equals(o);
return id.equals(rating.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
controller
#RequestMapping(value = "/user", method = RequestMethod.GET)
public String profile(Model model, HttpServletRequest request) {
// User user=populator.getUserFromSession();
HttpSession session = request.getSession(false);
User user = (User) session.getAttribute("user");
model.addAttribute("user", user);
if (user != null) {
List<MovieRecommendation> mr = movieRepository.getRecommendations(user.getLogin());
MovieRecommendation movie = new MovieRecommendation();
Movie m = new Movie();
m.setTitle("AA");
movie.setMovie(m);
mr.add(movie);
model.addAttribute("recommendations", mr);
}
return "user/index";
}![enter image description here][4]
It only loads the movie's id by default, if you don't specify #Fetch on the movie field. But I'd rather recommend to use template.fetch(rating.movie) to load it only when you need it.

Resources