Spring Data MongoDB with Java 8 LocalDate MappingException - spring

I try to use the LocalTime from Java 8 Date Time API with Spring Data MongoDB. Inserting the document works as expected, but when I try to read the document, I get the following error:
Exception in thread "main" java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:637)
....
Caused by: org.springframework.data.mapping.model.MappingException: No property null found on entity class java.time.LocalDate to bind constructor parameter to!
at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:74)
at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:63)
at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:71)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:257)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:237)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1109)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$100(MappingMongoConverter.java:78)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1058)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getValueInternal(MappingMongoConverter.java:789)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:270)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:263)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:261)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:263)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:237)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:201)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:197)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:78)
at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2005)
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1699)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1522)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1506)
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:532)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:217)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:174)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:44)
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:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:358)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy28.findAll(Unknown Source)
at hello.Application.run(Application.java:36)
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:634)
... 5 more
I tried this with the example from the Spring website: http://spring.io/guides/gs/accessing-data-mongodb/
I just changed to Customer to have a birthdate:
package hello;
import org.springframework.data.annotation.Id;
import java.time.LocalDate;
public class Customer {
#Id
private String id;
private String firstName;
private String lastName;
private LocalDate birthDay;
public Customer() {}
public Customer(String firstName, String lastName, LocalDate birthDay) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDay = birthDay;
}
#Override
public String toString() {
return String.format(
"Customer[id=%s, firstName='%s', lastName='%s']",
id, firstName, lastName);
}
}

I wrote this little bit of code for all 4 of these conversion options:
DateToLocalDateTimeConverter
DateToLocalDateConverter
LocalDateTimeToDateConverter
LocalDateToDateConverter
Here is an example
public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
#Override
public LocalDateTime convert(Date source) {
return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
All example here.
Then by including this in the xml configuration for the mongodb connection I was able to work in java 8 dates with mongodb (remember to add all the converters):
<mongo:mapping-converter>
<mongo:custom-converters>
<mongo:converter>
<bean class="package.DateToLocalDateTimeConverter" />
</mongo:converter>
</mongo:custom-converters>
</mongo:mapping-converter>

Now problem is resolved:
https://jira.spring.io/browse/DATAMONGO-1102
But Spring Data doesn't support ZonedDateTime now, only Local.

This is currently not supported mostly due to the fact that MongoDB doesn't support storing Java 8 date time types right now. I suggest to turn the internal property into a legacy Date one and do the conversions on the API of the domain class (as you would do with Hibernate and JodaTime e.g.).

Related

Compilation error using both HashKey and RangeKey in dynamoDB with Springboot

I am using dynamDb with my springboot application. I am trying to save data in the table which has hashKey and sortKey. Initially I tried to annotate my HaskKey and sortKey with #DynamoDBHashKey and #DynamoDBRangeKey respectively. However this was giving me compilation issues. Upon search I found this article https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys which explains how in springboot we need to create a composite key/id with annotation #id. This id will not be part of the table.
I implemented the same however I still get compilation error:
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eventRepository' defined in com.accuity.kyc.hep.repository.EventRepository defined in #EnableDynamoDBRepositories declared on DynamoDBConfig: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/repository/core/support/ReflectionEntityInformation\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)\r\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944)\r\n\tat org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)\r\n\tat org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)\r\n\tat org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)\r\n\tat org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)\r\n\tat org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:302)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)\r\n\tat com.accuity.kyc.hep.HepApplication.main(HepApplication.java:16)\r\nCaused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'historyEventRepository' defined in com.accuity.kyc.hep.repository.HistoryEventRepository defined in #EnableDynamoDBRepositories declared on DynamoDBConfig: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/repository/core/support/ReflectionEntityInformation\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)\r\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)\r\n\tat org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)\r\n\t... 19 common frames omitted\r\nCaused by: java.lang.NoClassDefFoundError: org/springframework/data/repository/core/support/ReflectionEntityInformation\r\n\tat java.base/java.lang.ClassLoader.defineClass1(Native Method)\r\n\tat java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)\r\n\tat java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)\r\n\tat java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)\r\n\tat java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityMetadataSupport.getEntityInformation(DynamoDBEntityMetadataSupport.java:125)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactory.getEntityInformation(DynamoDBRepositoryFactory.java:104)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactory.getDynamoDBRepository(DynamoDBRepositoryFactory.java:128)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactory.getTargetRepository(DynamoDBRepositoryFactory.java:150)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:324)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:322)\r\n\tat org.springframework.data.util.Lazy.getNullable(Lazy.java:230)\r\n\tat org.springframework.data.util.Lazy.get(Lazy.java:114)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:328)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)\r\n\t... 30 common frames omitted\r\nCaused by: java.lang.ClassNotFoundException: org.springframework.data.repository.core.support.ReflectionEntityInformation\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)\r\n\tat java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)\r\n\tat java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)\r\n\t... 50 common frames omitted\r\n"}
My entity class looks like this:
#DynamoDBTable(tableName = "Event")
#NoArgsConstructor
public class Event {
#Id
private EventId eventId;
#DynamoDBHashKey(attributeName = "id")
#DynamoDBAutoGeneratedKey
public String getId() {
return eventId != null ? eventId.getId() : null;
}
public void setId(String id) {
if (eventId == null) {
eventId = new eventId();
}
eventId.setId(id);
}
#DynamoDBRangeKey(attributeName = "eventDate")
public Date getEventDate() {
return eventId != null ? eventId.getEventDate() : null;
}
public void setEventDate(Date eventDate) {
if (eventId == null) {
eventId = new eventId();
}
eventId.setEventDate(eventDate);
}
}
Composite key class:
#NoArgsConstructor
#AllArgsConstructor
public class EventId {
private String id;
private Date eventDate;
#DynamoDBHashKey(attributeName = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBRangeKey(attributeName = "eventDate")
public Date getEventDate() {
return eventDate;
}
public void setEventDate(Date eventDate) {
this.eventDate = eventDate;
}
}
Repository:
#EnableScan
#Repository
public interface EventRepository extends CrudRepository<Event, EventId> {
}
For dependency I am using:
id 'org.springframework.boot' version '2.6.1' and
com.github.derjust:spring-data-dynamodb:5.1.0
I have followed the similar example from couple of other sources. I can not see what am I missing.
Please help.
There is an open issue for this, https://github.com/derjust/spring-data-dynamodb/issues/279. It appears the library is not compatible with Spring Boot 2.2. Per one of the commenters there is a fork available that may support this, but I haven't found this yet.
EDIT: The repository where this supposedly works now is at https://github.com/boostchicken/spring-data-dynamodb.

SpringBoot JPA repository save method not working

I will get List of JSONs from my MobileApp and I am converting those to a DataModel and then trying to insert the list of dataModel as a bulk.
This is my Data Model or Entity Object.
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.OffsetDateTime;
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "cab_boarding")
public class CabBoardingModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
#Column(name = "gpid")
String gpid;
#Column(name = "latitude")
Long latitude;
#Column(name = "longitude")
Long longitude;
#Column(name = "vehicle_number")
String vehicleNumber;
#Column(name = "boarding_time")
OffsetDateTime boardingTime;
}
This is my Repository Interface
public interface CBRepository extends CrudRepository<CabBoardingModel, Long> {
List<CabBoardingModel> findAll();
List<CabBoardingModel> save(List<CabBoardingModel> cabBoardingModels);
Optional<CabBoardingModel> findById(Long id);
}
Below is the service tier that calls this save method
#Service
public class CBService {
private CBRepository cbRepository;
#Autowired
public CBService(CBRepository cbRepository) {
this.cbRepository = cbRepository;
}
public List<CabBoardingModel> create(List<CabBoardingModel> cabBoardingModelList) {
List<CabBoardingModel> cbCreatedList = cbRepository.save(cabBoardingModelList);
return cbCreatedList;
}
}
Getting the below exception while accessing the save method
2018-02-15 23:49:03.407 ERROR [smpoc-service-cabboarding,1b921dc7bf735306,1b921dc7bf735306,false] 2988 --- [nio-8080-exec-1] f.c.b.a.w.e.h.ControllerExceptionHandler : Unexpected exception
org.springframework.beans.NotReadablePropertyException: Invalid property 'id' of bean class [java.util.ArrayList]: Could not find field for property during fallback access!
at org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper.getPropertyValue(DirectFieldAccessFallbackBeanWrapper.java:56) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.getId(JpaMetamodelEntityInformation.java:149) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.data.repository.core.support.AbstractEntityInformation.isNew(AbstractEntityInformation.java:51) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.isNew(JpaMetamodelEntityInformation.java:227) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:507) ~[spring-data-jpa-1.11.10.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:513) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:498) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:475) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
The saveAll method in Spring Data is only available with Spring Data 2.x (the link you provided links always to the documentation of the latest version). However, with Spring Boot 1.5, it uses an older Spring Data version, where the following documentation applies: https://docs.spring.io/spring-data/data-commons/docs/1.13.10.RELEASE/api/
As you can see, here the method signature is
<S extends T> Iterable<S> save(Iterable<S> entities)
You should add #Transactional annotation to your method, so spring will handle the transaction and commit your changes.
This usually comes on the #Service class, but I see in your example that you do not have one, so put it on the controller (or add a service layer, I think it's better)

Spring Cassandra Custom Repository for TTL Save

I'm trying use a custom repository to save an entity with a TTL (Time to Live) value. I've have done a lot of searching and read the docs online, but I'm still getting an exception.
Any help gratefully appreciated.
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property saveWithTTL found for type Task!
The snippets are as follows:
Task (the entity):
#Table
public class Task {
#PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private String uuid;
private Type type;
private Status status;
private String parentId;
private String body;
}
CassandraDbConfig:
#Configuration
#PropertySource(value = "classpath:cassandra.properties")
#EnableCassandraRepositories(repositoryBaseClass = TTLRepositoryCustomImpl.class)
public class CassandraDbConfig extends DefaultCassandraConfig {
}
TTLRepositoryCustom:
#NoRepositoryBean
public interface TTLRepositoryCustom<T> extends CassandraRepository<T> {
T saveWithTTL(T entity, Integer ttl);
}
TTLRepositoryCustomImpl:
public class TTLRepositoryCustomImpl<T> extends SimpleCassandraRepository<T, MapId>implements TTLRepositoryCustom<T> {
public TTLRepositoryCustomImpl(final CassandraEntityInformation<T, MapId> metadata,
final CassandraOperations operations) {
super(metadata, operations);
}
#Override
public T saveWithTTL(T entity, Integer ttl) {
WriteOptions options = new WriteOptions();
options.setTtl(ttl);
return operations.insert(entity, options);
}
}
TaskDbRepository:
#Repository
public interface TaskDbRepository extends TTLRepositoryCustom<Task> {
}
Full stack trace:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property saveWithTTL found for type Task!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:77)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:247)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:398)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:378)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:86)
at org.springframework.data.cassandra.repository.query.PartTreeCassandraQuery.<init>(PartTreeCassandraQuery.java:47)
at org.springframework.data.cassandra.repository.support.CassandraRepositoryFactory$CassandraQueryLookupStrategy.resolveQuery(CassandraRepositoryFactory.java:163)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:436)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:221)
You can use something like this in a spring boot application inside a service class (with other 'normal' cassandra repo in place in the application), TTL will be in seconds, I know you are asking for a complete TTL-repo implementation, but this can be handy if you want just to save that with TTL.
#Autowired
private CassandraOperations cassandraOperations;
private void saveWithTTL(Task task)
{
String cql = "insert into task (uuid, body) values ('"+task.getUuid()+"', "+task.getBody()+") USING TTL 86400;";
cassandraOperations.execute(cql);
}

Spring Data query over two documents

I have an m:n connection in my MongoDB, MessageUserConnection is the class between User and Message.
Now I will get all MessageUserConnections where MessageUserConnection#confirmationNeeded is true, read is false and Message#receiveDate is not older than the last week.
Is there any possibility to do this with Spring Data?
Thanks a lot!
public class MessageUserConnection {
#Id
private String id;
#DBRef
private User userCreatedMessage;
#DBRef
private Message message;
private Boolean confirmationNeeded;
private Boolean read;
}
public class Message {
#Id
private String id;
private String title;
private String message;
private DateTime receiveDate;
}
[EDIT]
I have tried it by my own:
#Query("FROM MessageUserConnection AS muc WHERE muc.confirmationNeeded = ?0 AND muc.message.receiveDate = ?1")
List<MessageUserConnection> findMessageUserConnectionByConfirmationNeededAndReceiveDate(final Boolean confirmationNeeded, final DateTime receiveDate);
and I get the following exception:
Caused by: com.mongodb.util.JSONParseException:
FROM MessageUserConnection AS muc WHERE muc.confirmationNeeded = "_param_0" AND muc.message.receiveDate = "_param_1"
Does anyone know what I am doing wrong here?
Thanks a lot!
[EDIT]
I run into another problem. My query currently looks like this.
#Query("{$and : [{'confirmationNeeded' : ?0}, {'message.receiveDate' : ?1}]}")
where confirmationNeeded is a boolean and message.receiveDate is Joda#DateTime. With this query I get the following exception:
org.springframework.data.mapping.model.MappingException: Invalid path reference message.receiveDate! Associations can only be pointed to directly or via their id property!
Does that mean that I only can join to message.id?
Thanks a lot!

Spring Data Neo4j - Getting an exception when running a cypher query

I'm getting a strange exception when trying to run a simple cypher query. First i'll introduce my code, and then i'll show what cause the exception. So i have the following classes:
A simple class to represent a user profile:
public abstract class Profile extends AbstractEntity {
#Indexed
ProfileType profileType;
#Indexed(indexType = IndexType.FULLTEXT, indexName = "name")
String firstName;
#Indexed(indexType = IndexType.FULLTEXT, indexName = "name")
String lastName;
#Indexed
EyeColor eyeColor;
#Indexed
HairColor hairColor;
#Indexed
Nationality nationality;
#Indexed
int height;
public Profile() {
setProfileType();
}
public Profile(String firstName, String lastName, Nationality nationality, EyeColor eyeColor, HairColor hairColor, int height) {
this();
this.setFirstName(firstName);
this.setLastName(lastName);
this.setNationality(nationality);
this.setHairColor(hairColor);
this.setEyeColor(eyeColor);
this.setHeight(height);
}
/* Getters and Setters */
}
And a simple class, which inherit from Profile, and represents a civilian:
#NodeEntity
public class Civilian extends Profile {
#GraphProperty(propertyType = Long.class)
DateTime dateOfBirth;
#Indexed
boolean missing;
#RelatedTo
#Fetch
Set<Casualty> casualties = new HashSet<Casualty>(); //TODO: design
public Civilian() {
this.profileType = ProfileType.CIVILIAN;
}
public Civilian(String firstName, String lastName, Nationality nationality, EyeColor eyeColor, HairColor hairColor, int height, DateTime dateOfBirth, boolean missing) {
super(firstName, lastName, nationality, eyeColor, hairColor, height);
this.setDateOfBirth(dateOfBirth);
this.setMissing(missing);
}
/* Getters and Setters */
}
So i created the following repository for the Civilian class:
public interface CivilianRepository extends GraphRepository<Civilian> {
#Query("start n=node(*) where n.firstName=~{0} return n")
Page<Civilian> findCiviliansProperties(String firstName, Pageable page);
}
Ok. So i created few Civilian nodes, and populated the graph with them. There are no other nodes in the graph, except for the Civilian nodes. When i run the findCiviliansProperties method, i get the following exception:
Exception in thread "main" org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement start n=node(*) where n.firstName=~{0} return n skip 0 limit 10; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement start n=node(*) where n.firstName=~{0} return n skip 0 limit 10; nested exception is org.neo4j.cypher.EntityNotFoundException: The property 'firstName' does not exist on Node[0]
at org.springframework.data.neo4j.support.query.CypherQueryEngine.query(CypherQueryEngine.java:52)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.dispatchQuery(GraphRepositoryQuery.java:98)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.execute(GraphRepositoryQuery.java:81)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:312)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy33.findCiviliansProperties(Unknown Source)
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.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
at com.sun.proxy.$Proxy36.findCiviliansProperties(Unknown Source)
at org.technion.socialrescue.playground.Playground.main(Playground.java:38)
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement start n=node(*) where n.firstName=~{0} return n skip 0 limit 10; nested exception is org.neo4j.cypher.EntityNotFoundException: The property 'firstName' does not exist on Node[0]
at org.springframework.data.neo4j.support.query.CypherQueryEngine.parseAndExecuteQuery(CypherQueryEngine.java:63)
at org.springframework.data.neo4j.support.query.CypherQueryEngine.query(CypherQueryEngine.java:49)
... 20 more
Caused by: org.neo4j.cypher.EntityNotFoundException: The property 'firstName' does not exist on Node[0]
at org.neo4j.cypher.internal.commands.expressions.Property.apply(Property.scala:35)
at org.neo4j.cypher.internal.commands.expressions.Property.apply(Property.scala:29)
at org.neo4j.cypher.internal.commands.RegularExpression.isMatch(Predicate.scala:259)
at org.neo4j.cypher.internal.pipes.FilterPipe$$anonfun$createResults$1.apply(FilterPipe.scala:29)
at org.neo4j.cypher.internal.pipes.FilterPipe$$anonfun$createResults$1.apply(FilterPipe.scala:29)
at scala.collection.Iterator$$anon$22.hasNext(Iterator.scala:390)
at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334)
at scala.collection.Iterator$class.isEmpty(Iterator.scala:272)
at scala.collection.Iterator$$anon$19.isEmpty(Iterator.scala:333)
at org.neo4j.cypher.internal.pipes.SlicePipe.createResults(SlicePipe.scala:32)
at org.neo4j.cypher.internal.pipes.ColumnFilterPipe.createResults(ColumnFilterPipe.scala:37)
at org.neo4j.cypher.internal.executionplan.ExecutionPlanImpl$$anonfun$6.apply(ExecutionPlanImpl.scala:127)
at org.neo4j.cypher.internal.executionplan.ExecutionPlanImpl$$anonfun$6.apply(ExecutionPlanImpl.scala:125)
at org.neo4j.cypher.internal.executionplan.ExecutionPlanImpl.execute(ExecutionPlanImpl.scala:33)
at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:59)
at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:63)
at org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:79)
at org.springframework.data.neo4j.support.query.CypherQueryEngine.parseAndExecuteQuery(CypherQueryEngine.java:61)
... 21 more
Caused by: org.neo4j.graphdb.NotFoundException: 'firstName' property not found for NodeImpl#0.
at org.neo4j.kernel.impl.core.Primitive.newPropertyNotFoundException(Primitive.java:184)
at org.neo4j.kernel.impl.core.Primitive.getProperty(Primitive.java:179)
at org.neo4j.kernel.impl.core.NodeImpl.getProperty(NodeImpl.java:52)
at org.neo4j.kernel.impl.core.NodeProxy.getProperty(NodeProxy.java:155)
at org.neo4j.cypher.internal.commands.expressions.Property.apply(Property.scala:33)
... 38 more
So the most important thing about this exception is the following line - The property 'firstName' does not exist on Node[0].. But how can it be? there are only Civilian nodes in the graph, and they all have the firstName property. Can it be that the neo4j framework adds some more hidden nodes to my graph which i'm not aware of? Because when i change my query into this:
start n=node(*) where has(n.firstName) AND n.firstName=~{0} return n
Everything works fine...
What is wrong?
Thanks!!
neo4j automatically comes with 1 node when you create a new instance, and that's the reference node. You should delete this.
graphDatabaseService.getNodeById(0).delete()

Resources