Spring boot 3 org.hibernate.query.SemanticException when updating an enum data type - spring-boot

With the following code,
Entity:
#Column
#Enumerated(value = EnumType.STRING)
private MyStatusEnum status;
public enum MyStatusEnum {
ENABLED,
DISABLED
}
Repository method:
#Transactional
#Modifying
#Query("UPDATE MyEntityClass e SET e.status = 'ENABLED'")
int setEnabledStatus();
When trying to start the application i got the following exception:
... Caused by: org.hibernate.query.SemanticException: The assignment exppression type [java.lang.String] did not match the assignment path type [...MyStatusEnum] for the path [e.status] [UPDATE MyEntityClass e SET e.status = 'ENABLED']
Has anyone experienced the same issue?
I'm using spring boot 3.0.2

You have to use the enum value not a string:
#Transactional
#Modifying
#Query("UPDATE MyEntityClass e SET e.status = MyStatusEnum.ENABLED")
int setEnabledStatus();
because JPA works with Objects

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();
}

Spring JPA naming query with orderBy doesn't work

I'm using Spring Boot 2, Spring JPA, Spring Data.
I'm trying to get the first result from a table in which I want to sort results by a int property asc.
This is my bean:
#Entity
public class DatabaseInstance extends AbstractEntity {
#NotNull
#Enumerated(EnumType.STRING)
#Column(nullable = false)
private Supplier supplier;
NotNull
#Column(nullable = false, columnDefinition = "INT DEFAULT 0.0")
private int databaseCount = 0;
and this is my repository:
#Transactional
public interface DatabaseInstanceRepository extends JpaRepository<DatabaseInstance, Long> {
public Optional<DatabaseInstance> findFirstOrderByDatabaseCountAsc();
}
According to Spring manual I can order by property name + asc word. At the same time I want the first result (so i get the instance with the lower databaseCount value).
I get this error:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property asc found for type int! Traversed path: DatabaseInstance.databaseCount.
I am not able to figure out what's wrong with my method name. Some advice?

Spring Data JPA native query result binding

Entity class:
#Entity
#SqlResultSetMapping(
name="hourMapping",
classes=#ConstructorResult(
targetClass=Representation.class,
columns={
#ColumnResult(name="hour", type=BigDecimal.class),
#ColumnResult(name="transactions", type=BigDecimal.class)
}
)
)
#NamedNativeQuery(name="MyEntity.reportByHour", query="SELECT hour,SUM(tran_per_hour) AS transactions FROM MY_ENTITY GROUP BY hour ORDER BY hour"
,resultSetMapping="hourMapping")
#Table(name="MY_ENTITY")
public class MyEntity implements Serializable {
Pojo class:
#Data //Lombok
#JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class Representation {
public Representation(BigDecimal hour, BigDecimal transactions) {
this.hour = hour;
this.transactions = transactions;
}
private BigDecimal hour;
private BigDecimal transactions;
Repository interface:
public interface MyEntityRepository extends JpaRepository<MyEntity, MyEntityPK> {
List<Representation> reportByHour();
}
When I run the endpoint which invokes the native query, I get exception:
Failed to convert from type [java.lang.Object[]] to type [com.representation.Representation] for value '{0, 198}'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.math.BigDecimal] to type [com.representation.Representation]
Now if I just have "hour" field returned from my native query (and relevant changes to POJO constructor etc) it works fine.
Any help appreciated.
Ok, false alarm. My hibernate dependencies were all messed up and causing conflicts so resulting in the above exception.
After fixing these dependency issues, works great!!
Long story short: let spring-boot-* handle most hibernate dependencies instead of overriding or managing your own.

BeanPropertyRowMapper does not understand joda time types anymore since upgrading to spring boot 1.4 / spring cloud camden

I have a Spring Batch Job that defines a JdbcPagingItemReader with a BeanPropertyRowMapper :
JdbcPagingItemReader<RawNotice> reader = new JdbcPagingItemReader<>();
final SqlPagingQueryProviderFactoryBean sqlPagingQueryProviderFactoryBean = new SqlPagingQueryProviderFactoryBean();
sqlPagingQueryProviderFactoryBean.setDataSource(dataSource);
sqlPagingQueryProviderFactoryBean.setSelectClause("select *");
sqlPagingQueryProviderFactoryBean.setFromClause("from a_table");
sqlPagingQueryProviderFactoryBean.setWhereClause("state = :state");
sqlPagingQueryProviderFactoryBean.setSortKey("id");
Map<String, Object> parameters = new HashMap<>();
parameters.put("state", "interesting_state");
reader.setQueryProvider(sqlPagingQueryProviderFactoryBean.getObject());
reader.setDataSource(dataSource);
reader.setPageSize(10);
// The line below is the interesting one
reader.setRowMapper(new BeanPropertyRowMapper<>(MyEntity.class));
reader.setParameterValues(parameters);
return reader;
This used to work fine, but since we upgraded to spring boot 1.4 and spring cloud Camden, it throws an exception :
org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type [java.sql.Timestamp] to required type [org.joda.time.LocalDateTime] for property 'ADateColumn'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.sql.Timestamp] to required type [org.joda.time.LocalDateTime] for property 'ADateColumn': no matching editors or conversion strategy found
The column ADateColumn is declared as a Joda LocalDateTime and stored as a java.sql.Timestamp in the database.
I'm quite aware I could add my own joda converters to the BeanPropertyRawMapper conversionService for example, or create a PropertyEditor that understands Java LocalDateTime, but that looks rather like a configuration problem, like something isn't being registered right.
Anybody with a solution/suggestion to fix this problem ?
Thanks !
This is the part of the entity that poses problem :
#Entity
#EqualsAndHashCode(of = { "..." })
#ToString(of = { .... })
public class MyEntity {
#Getter
#Setter
#Id
#GeneratedValue
private Long id;
#Getter
#Version
#Column(nullable = false)
private int version;
//<--- snip --->
#Getter
#Setter
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime aDateColumn;
}
Hibernate is version 4.3.11.Final
JPA is version 2.1 with Hibernate Entity Manager 4.3.11.Final
So I finally ended up creating my own BeanPropertyRowMapper with custom Joda converters :/

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

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.

Resources