spring-data-cassandra, Cassandra storing List<Integer> as field - spring

I have problem storing field of List as field of my table in cassandra database.
I'm using spring-data-cassandra, version 1.4.1.RELEASE.
My model contains:
#Column
#CassandraType(type = DataType.Name.LIST)
private List<Integer> somedata;
I would like to auto create my db tables with SchemaAction.RECREATE_DROP_UNUSED Schema action in my config class:
#Override
public SchemaAction getSchemaAction() {
return SchemaAction.RECREATE_DROP_UNUSED;
}
It tries to create table, but following exception occurs:
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: expected 1 of typed arguments for the property 'somedata' type is 'interface java.util.List' in the entity <my class here>

Ok, found solution after digging into spring-data-cassandra source:
#CassandraType(type = DataType.Name.LIST, typeArguments = { DataType.Name.FLOAT } )
private List<Float> position;
You need to add typeArguments, to specify DataType of generic type. Exception mentioned in question is thrown when invalid number of those typeArguments is passed. In my case there was 0 and 1 is required.
#Column annotation proved to be not required here.

There is no need to provide CassandraType annotation over the field as long as you are using primitive or Wrapper type objects.
Following works fine for me.
#PrimaryKey
int id;
String name;
int num;
List<Integer> marks;
I am using spring-data-cassandra with version 1.4.2.RELEASE.
Please update if you still face the issue.

Related

Using projection with a interface in `#Query` annotation with a native query gives "Target type is not an interface and no matching Converter found"

I have a table with a clob in an oracle 19 database which I try to fetch with a native query using a #Query annotation with a projection from a Spring boot 2.7.4 application. I get the following error message:
java.lang.UnsupportedOperationException: Cannot project jdk.proxy2.$Proxy281 implementing java.sql.Clob,org.hibernate.engine.jdbc.WrappedClob,java.io.Serializable to java.lang.String; Target type is not an interface and no matching Converter found
The query from my repository class:
#Query(
value = """
select submission_id as "submissionId", text as "textAnswer"
from answer
where answer_id = :answerId
""",
nativeQuery = true)
public MyDTO findDTO(Long answerId);
My interface which I use for the projection:
public interface MyDTO {
String getTextAnswer();
}
From my domain object annotated with #Entity:
private String textAnswer;
My testcase which reproduce which reproduce this error. If I comment out the line with a.getTextAnswer() it runs ok.
#Test
public void findFormPublishedAnswersInterfaceDTOById() {
FormPublishedAnswersInterfaceDTO a = answerRepository.findFormPublishedAnswersInterfaceDTOById(21540241L);
assertEquals("test", a.getTextAnswer());
}
I have tried different hints I found by the help of google :) like annotating private String textAnswer with #Lob, #Type(type = "text") and #Column(name = "text", columnDefinition = "CLOB") without any luck.
If you read the exception carefully, you should understand that the JDBC driver reports that the type is a Clob, so your DTO must look like this instead:
public interface MyDTO {
Clob getTextAnswer();
}

Not able to search data in redis cache using spring crud repository by passing list of values for a property of the model saved in cache

We have model class saved in Redis as mentioned below:-
#Data
#NoArgsConstructor
#AllArgsConstructor
#RedisHash("book")
public class Book implements Serializable {
private static final long serialVersionUID = 2208852329346517265L;
#Id
private Integer bookID;
#Indexed
private String title;
#Indexed
private String authors;
private String averageRating;
private String isbn;
private String languageCode;
private String ratingsCount;
private BigDecimal price;
}
We have title and authors as our indexed property.
Now we wanted to search all the records from Redis by passing title and a list of authors using the spring crud repository as mentioned below.
public interface BookSpringRepository extends CrudRepository<Book, String> {
List<Book> findAllByTitleAndAuthors(String title, List<String> authors);
}
Service layer:-
#Override
public Optional<List<Book>> searchBooksByTitleAndAuthorNames(String title, List<String>
autherNames) {
return Optional.ofNullable(bookSpringRepository.findAllByTitleAndAuthors(title,
autherNames));
}
Here we are getting below exception
Unable to fetch data from Spring data Redis cache using List of Integer or
String.
Getting error while fetching - "Resolved
[org.springframework.core.convert.ConversionFailedException: Failed to convert from type
[java.lang.String] to type [byte] for value 'Ronak';
nested exception is java.lang.NumberFormatException: For input string: "Ronak"]."
We would not want to convert the list of string/integer to byte as it is a time-consuming process and as we tried took so much amount of time. Also when the results are retrieved we will again have to convert back to normal integer or string values.
The other option is to loop through the list and pass a single value at a time to the Redis crud repository and this time Redis crud repository is happy but that will be a loop call to Redis and network latency.
We cannot add ID attributes on authors' property as these can be duplicate records.
Does the spring crud repository support the LIKE query in search that way we can create a unique id having these authors' names and make put ID annotation on that new derived property to search the records using spring crud repository using LIKE or contains kind of query.
Any suggestions here are highly appreciated!!
Try to add serialization to your redis key and value. This might help :
https://medium.com/#betul5634/redis-serialization-with-spring-redis-data-lettuce-codec-1a1d2bc73d26

How to get recent record by a field and ordered by date (complex query)?

I am trying to write a method in spring data to get last recod by text and ordered by updateDate.
My entity look like :
#Entity
public class Command {
#Id
#GeneratedValue
private Long id;
#Column(nullable = false)
private String text;
// epoch date
private Long updateDate;
/* Getters and Setters */
}
And this is the repository:
public interface CommandRepository extends JpaRepository<Command, Long> {
Command findByTextAndTopByUpdateDateDesc(String text);
}
Of course, find by text method must give me more thant one reocord but by filtering with top date will get only one record !
the methode above return the following error :
Caused by:
org.springframework.data.mapping.PropertyReferenceException: No
property TopByUpdateDateDesc found for type Command! at
org.springframework.data.mapping.PropertyPath.(PropertyPath.java:94)
I tried to check some stackoverflow postes to find any solution but nada !
Is there any solution to that case or i have to use native query ?
The ordering in your query method is wrong. You first need the limitations (Top/First) before you do the where part and you end with the ordering. This is also what the error, given a bit cryptic, is telling you.
Instead of findByTextAndTopByUpdateDateDesc you should use something like findFirstByTextOrderByUpdateDateDesc.
The ordering etc. is explained in the Spring Data JPA documentation.

Spring Data JPA - How to find by param with underscore

Here is my model:
public class Log {
#Id
private String id;
private String project;
private String test_no;
// Constructor, getters and setters.
}
How can I add a findBy query which allows me to finding an element by its test_no value? I have tried those method headers but they don't work:
List<Log> findByTest_No(String test_no);
The error that my STS reports is: Invalid delivery query! No property test found in type Log!
List<Log> findByTest_no(String test_no);
The error that my STS reports is: Invalid delivery query! No property test found in type Log!
List<Log> findByTestno(String test_no);
The error that my STS reports is: Invalid derived query! No property testno found for type Log! Did you mean 'test_no'?
It seems that _ is a special character which separates properties names
... it is possible for the algorithm to select the wrong property ... To resolve this ambiguity you can use \_ inside your method name to manually define traversal points ...
Docs
So it can't find test field in Log class.
Try to use:
#Query("select log from Log log where log.test_no = ?1")
List<Log> findByTestNo(String testNo);
There is no need to use private String test_no; You may use private String testNo; Spring automatically understand that you are binding test_no column in the database. Also you can use
#Column(name = "test_no")
private String testNo;
After this changes you can execute queries, mentioned in your question without any custom sql.
List<Log> findByTestNo(String testNo);

Spring Data MongoDB repository method delete by list of id

I have the following document:
#Document(collection = "decision_analysis")
public class DecisionAnalysis implements Serializable {
#Id
private String id;
...
}
I need to delete multiple MongoDB documents via List<String> decisionAnalysisIds
How to properly write Spring Data MongoDB repository method in order to do it?
The following doesn't work :
void deleteByIds(List<String> decisionAnalysisIds); - error: No property ids found for type DecisionAnalysis! Did you mean 'id'?
void deleteById(List<String> decisionAnalysisIds); - works, but delete only one document
Use the in clause like this:
void deleteByIdIn(List<String> ids);

Resources