[JIRA] (HHH-17021) Composite primary key is altered when part of it is from a lazy non optional ManyToOne
by Erwan Moutymbo (JIRA)
Erwan Moutymbo ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=640210c... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiODJhYzU4ZTA4... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-17021?atlOrigin=eyJpIjoiODJhYz... ) HHH-17021 ( https://hibernate.atlassian.net/browse/HHH-17021?atlOrigin=eyJpIjoiODJhYz... ) Composite primary key is altered when part of it is from a lazy non optional ManyToOne ( https://hibernate.atlassian.net/browse/HHH-17021?atlOrigin=eyJpIjoiODJhYz... )
Issue Type: Bug Affects Versions: 6.3.0.CR1, 6.2.7, 6.3.0, 6.2.8 Assignee: Unassigned Components: hibernate-core Created: 01/Aug/2023 09:20 AM Environment: Hibernate: 6.2.8-SNAPSHOT
initially found with Postgresql: 14.5
reproduced with h2 2.1.214
Spring Data JPA: 3.0.6
Spring Boot: 3.0.7
ehcache 3.10.8
JDK: OpenJDK 64-Bit Server VM Temurin-17.0.6
OS: Fedora 38 Priority: Major Reporter: Erwan Moutymbo ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=640210c... )
Hello, I'm migrating from hibernate 5.6.15 to hibernate 6.2 and I have noticed some issues. it seems that I can’t use a composite primary key when part of it is from a lazy non optional ManyToOne, as it gives me a error saying primary key was altered.
--------
Entities
--------
note
----
I had to use tiny ints for my enums due to https://hibernate.atlassian.net/browse/HHH-17020
Product
-------
@Getter
@IdClass(ProductPK.class)
@EqualsAndHashCode(onlyExplicitlyIncluded = true )
@ToString(onlyExplicitlyIncluded = true )
@NoArgsConstructor(access = PROTECTED)
@Entity
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@DynamicUpdate
@Cacheable
@Cache(usage = READ_WRITE)
@Table(name = "PRODUCTS" )
public class Product {
public Product( String productId, Operator operator ) {
this.productId = productId;
this. operator = operator ;
}
public Product( String productId, Operator operator , Benefits benefits) {
this.productId = productId;
this. operator = operator ;
this.benefits = benefits;
}
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Column(name = "PRODUCT_ID" , nullable = false )
private String productId;
@Id
@EqualsAndHashCode.Include
@ToString.Include
@Getter
@Setter
@Cache(usage = READ_WRITE)
@ManyToOne(fetch = LAZY, optional = false )
@JoinColumn(name = "OPERATOR_ID" , nullable = false )
@JoinColumn(name = "COUNTRY" , nullable = false )
private Operator operator ;
@Column(name = "DESCRIPTION" )
@Setter
private String description;
@Embedded
private Benefits benefits;
@EqualsAndHashCode
@ToString
@Embeddable
@NoArgsConstructor(access = PROTECTED)
public static class ProductPK implements Serializable {
private String productId;
@Embedded
@AttributeOverride(name = "operatorId" , column = @Column(name = "OPERATOR_ID" , nullable = false ))
@AttributeOverride(name = "country" ,
column = @Column(name = "COUNTRY" , nullable = false ))
private Operator.OperatorPK operator ;
public ProductPK( String productId, Operator.OperatorPK operator ) {
this.productId = productId;
this. operator = operator ;
}
public ProductPK( String productId, String operatorID, Country country) {
this.productId = productId;
this. operator = new Operator.OperatorPK(operatorID, country);
}
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class Benefits {
@Embedded
@NonFinal
@Setter
TypeOneBenefit credit;
@Embedded
@NonFinal
@Setter
TypeTwoBenefit data;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class TypeOneBenefit {
@NonFinal
@Column(name = "BENEFIT_ONE_BASE_AMOUNT" )
BigDecimal baseAmount;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class TypeTwoBenefit {
@NonFinal
@Column(name = "BENEFIT_TWO_BASE_AMOUNT" )
String baseAmount;
}
}
Operator
--------
@Getter
@Entity
@ToString(onlyExplicitlyIncluded = true )
@EqualsAndHashCode(onlyExplicitlyIncluded = true )
@NoArgsConstructor(access = PROTECTED)
@Table(name = "OPERATORS" )
@IdClass(Operator.OperatorPK.class)
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@DynamicUpdate
@Cacheable
@Cache(usage = READ_WRITE)
public class Operator {
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Column(name = "COUNTRY" , nullable = false )
private Country country;
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Column(name = "OPERATOR_ID" , nullable = false )
private String operatorId;
@ManyToOne
@JoinColumn(name = "meta_operator_id" , referencedColumnName = "ID" )
private MetaOperator metaOperator;
@OneToMany(mappedBy = " operator " ,
cascade = { PERSIST, MERGE, REMOVE },
orphanRemoval = true ,
fetch = FetchType.LAZY)
private List<Product> products = new ArrayList<>();
public Operator( String operatorId) {
this.operatorId = operatorId;
this.country = USA;
}
public void setMetaOperator(MetaOperator metaOperator) {
this.metaOperator = metaOperator;
}
public void setProducts(List<Product> products) {
this.products = products;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class OperatorPK implements Serializable {
@NonFinal
String operatorId;
@NonFinal
Country country;
}
}
Country
-------
public enum Country {
USA,
FRA;
}
-----
Tests
-----
should delete product
---------------------
@Test
void shouldDeleteProduct() {
// Given
String string = "ID2" ;
String operatorID = "operatorID2" ;
String test = "test" ;
Operator operator = new Operator(operatorID);
operatorService.addOperator( operator );
Product product = new Product(string, operator );
product.setDescription(test);
productService.addProduct(product);
// When
ProductPK productPK = new ProductPK(string, operatorID, USA);
productService.deleteProduct(productPK);
// Then
Optional<Product> byId2 = productService.getProduct(productPK);
assertThat(byId2).isEmpty();
}
an exception occurs when product is being deleted :
org.springframework.orm.jpa.JpaSystemException: identifier of an instance of com.example.demo.local.Product was altered from Product.ProductPK(productId=ID2, operator=Operator.OperatorPK(operatorId=null, country=null)) to Product.ProductPK(productId=ID2, operator=Operator.OperatorPK(operatorId=operatorID2, country=USA))
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:320)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:229)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:565)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:660)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:410)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:702)
at com.example.demo.service.ProductService$$SpringCGLIB$$0.deleteProduct(<generated>)
at com.example.demo.service.ProductServiceTest.shouldDeleteProduct(ProductServiceTest.java:107)
...
All tests on ProductServiceWithCacheTest and ProductServiceTest fails except the test where the operator is delete so it cascade delete the product ( shouldDeleteProductsWithBenefitsFromOperator )
-------
Sources
-------
sources can be found in pk_altered_when_part_is_from_lazy_association : https://github.com/emouty/hibernate-issues/tree/pk_altered_when_part_is_f...
( https://hibernate.atlassian.net/browse/HHH-17021#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-17021#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100233- sha1:b4f309b )
10 months, 2 weeks
[JIRA] (HHH-17020) Can't use enum as string in join column when field is part of composite primary key
by Erwan Moutymbo (JIRA)
Erwan Moutymbo ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=640210c... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiYTk4YmE0Yzhm... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-17020?atlOrigin=eyJpIjoiYTk4Ym... ) HHH-17020 ( https://hibernate.atlassian.net/browse/HHH-17020?atlOrigin=eyJpIjoiYTk4Ym... ) Can't use enum as string in join column when field is part of composite primary key ( https://hibernate.atlassian.net/browse/HHH-17020?atlOrigin=eyJpIjoiYTk4Ym... )
Change By: Erwan Moutymbo ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=640210c... )
Hello, I'm migrating from hibernate 5.6.15 to hibernate 6.2 and I have noticed some issues. it seems that I can’t use an enum as a string with `@Enumerated( STRING )` when my enum is part of a composite primary key which itself is reference another composite primary key.
h2. Entities
h3. Product
{code:java}@Getter
@IdClass(ProductPK.class)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@ToString(onlyExplicitlyIncluded = true)
@NoArgsConstructor(access = PROTECTED)
@Entity
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@DynamicUpdate
@Cacheable
@Cache(usage = READ_WRITE)
@Table(name = "PRODUCTS")
public class Product {
public Product(String productId, Operator operator) {
this.productId = productId;
this.operator = operator;
}
public Product(String productId, Operator operator, Benefits benefits) {
this.productId = productId;
this.operator = operator;
this.benefits = benefits;
}
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Column(name = "PRODUCT_ID", nullable = false)
private String productId;
@Id
@EqualsAndHashCode.Include
@ToString.Include
@Getter
@Setter
@Cache(usage = READ_WRITE)
@ManyToOne(fetch = LAZY, optional = false)
@JoinColumn(name = "OPERATOR_ID", nullable = false)
@JoinColumn(name = "COUNTRY", nullable = false, columnDefinition = "varchar")
private Operator operator;
@Column(name = "DESCRIPTION")
@Setter
private String description;
@Embedded
private Benefits benefits;
@EqualsAndHashCode
@ToString
@Embeddable
@NoArgsConstructor(access = PROTECTED)
public static class ProductPK implements Serializable {
private String productId;
@Embedded
private Operator.OperatorPK operator;
public ProductPK(String productId, Operator.OperatorPK operator) {
this.productId = productId;
this.operator = operator;
}
public ProductPK(String productId, String operatorID, Country country) {
this.productId = productId;
this.operator = new Operator.OperatorPK(operatorID, country);
}
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class Benefits {
@Embedded
@NonFinal
@Setter
TypeOneBenefit credit;
@Embedded
@NonFinal
@Setter
TypeTwoBenefit data;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class TypeOneBenefit {
@NonFinal
@Column(name = "BENEFIT_ONE_BASE_AMOUNT")
BigDecimal baseAmount;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class TypeTwoBenefit {
@NonFinal
@Column(name = "BENEFIT_TWO_BASE_AMOUNT")
String baseAmount;
}
}{code}
h3. Operator
{code:java}
@Getter
@Entity
@ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@NoArgsConstructor(access = PROTECTED)
@Table(name = "OPERATORS")
@IdClass(Operator.OperatorPK.class)
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@DynamicUpdate
@Cacheable
@Cache(usage = READ_WRITE)
public class Operator {
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Enumerated(STRING)
@Column(name = "COUNTRY", nullable = false, columnDefinition = "varchar")
private Country country;
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Column(name = "OPERATOR_ID", nullable = false)
private String operatorId;
@ManyToOne
@JoinColumn(name = "meta_operator_id", referencedColumnName = "ID")
private MetaOperator metaOperator;
@OneToMany(mappedBy = "operator",
cascade = { CascadeType.ALL PERSIST, MERGE, REMOVE },
orphanRemoval = true,
fetch = FetchType.LAZY)
private List<Product> products = new ArrayList<>();
public Operator(String operatorId) {
this.operatorId = operatorId;
// default country
this.country = USA;
}
public void setMetaOperator(MetaOperator metaOperator) {
this.metaOperator = metaOperator;
}
public void setProducts(List<Product> products) {
this.products = products;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class OperatorPK implements Serializable {
@NonFinal
String operatorId;
@NonFinal
@Enumerated(STRING)
Country country;
}
}{code}
h4. note :
At first, I did not specify `columnDefinition = "varchar"` on Operator nor Product but I would get
{noformat}Error executing DDL "create table operators (country clob not null check (country in ('USA','FRA')), meta_operator_id varchar(255), operator_id varchar(255) not null, primary key (country, operator_id))" via JDBC [Fonctionnalité non supportée: "Index on column: ""COUNTRY"" CHARACTER LARGE OBJECT NOT NULL"
Feature not supported: "Index on column: ""COUNTRY"" CHARACTER LARGE OBJECT NOT NULL";]{noformat}
even though I had {{@Enumerated(STRING)}} on Operator.country
h3. Country
{code:java}public enum Country {
USA,
FRA;
}
{code}
h2. Tests
h3. addProductTest
{code:java} @Test
void addProductTest() {
String string = "ID";
String operatorID = "operatorID";
ProductPK id = new ProductPK(string, operatorID, USA);
String test = "test";
Operator operator = new Operator(operatorID);
operatorService.addOperator(operator);
Product product = new Product(string, operator);
product.setDescription(test);
productService.addProduct(product);
Optional<Product> byId = productService.getProduct(id);
assertThat(byId.orElseThrow().getDescription()).isEqualTo(test);
Optional<Product> byId2 = productService.readProduct(id);
assertThat(byId2.orElseThrow().getOperator().getOperatorId()).isEqualTo(operatorID);
}{code}
an exception occurs when {{productService.addProduct(product);}} is committed :
{noformat} at com.example.demo.service.ProductService$$SpringCGLIB$$0.addProduct(<generated>)
at com.example.demo.service.ProductServiceTest.addProductTest(ProductServiceTest.java:43)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Caused by: jakarta.persistence.RollbackException: Error while committing the transaction
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:65)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:561)
... 80 more
Caused by: java.lang.ClassCastException: class java.lang.Byte cannot be cast to class java.lang.String (java.lang.Byte and java.lang.String are in module java.base of loader 'bootstrap')
at org.hibernate.type.descriptor.java.StringJavaType.unwrap(StringJavaType.java:27)
at org.hibernate.type.descriptor.jdbc.VarcharJdbcType$1.doBind(VarcharJdbcType.java:108)
...
... 81 more{noformat}
h3. shouldDeleteOperator
{code:java} @Test
@Order(2)
void shouldDeleteOperator() {
// Given
String operatorID = "operatorID2";
Operator operator = new Operator(operatorID);
operatorDao.save(operator);
// When
operatorService.deleteOperator(new Operator.OperatorPK(operatorID, USA));
//Then
Optional<Operator> byId2 = operatorService.getOperator(operatorID);
assertThat(byId2).isEmpty();
}{code}
this one fails when committing the transaction for {{operatorService.deleteOperator}}
{noformat}org.springframework.dao.DataIntegrityViolationException: could not execute statement [Erreur lors de la conversion de données "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"
Data conversion error converting "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"; SQL statement:
delete from operators where country=? and operator_id=? and meta_operator_id is null [22018-214]] [delete from operators where country=? and operator_id=? and meta_operator_id is null]; SQL [delete from operators where country=? and operator_id=? and meta_operator_id is
...
Caused by: org.hibernate.exception.DataException: could not execute statement [Erreur lors de la conversion de données "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"
Data conversion error converting "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"; SQL statement:
delete from operators where country=? and operator_id=? and meta_operator_id is null [22018-214]] [delete from operators where country=? and operator_id=? and meta_operator_id is null]
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:53)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:56)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
...
... 80 more
Caused by: org.h2.jdbc.JdbcSQLDataException: Erreur lors de la conversion de données "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"
Data conversion error converting "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"; SQL statement:
delete from operators where country=? and operator_id=? and meta_operator_id is null [22018-214]{noformat}
h2. Sources
source code can be found in branch {{cant_use_enum_as_string_in_join_columns}} : [https://github.com/emouty/hibernate-issues/tree/cant_use_enum_as_string_i...]
for information all the tests in {{OperatorServiceTest}}, {{ProductServiceTest}}, {{ProductServiceWithCacheTest}} are failing.
( https://hibernate.atlassian.net/browse/HHH-17020#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-17020#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100233- sha1:b4f309b )
10 months, 2 weeks
[JIRA] (HHH-17020) Can't use enum as string in join column when field is part of composite primary key
by Erwan Moutymbo (JIRA)
Erwan Moutymbo ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=640210c... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiOTMzNDQzYTgx... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-17020?atlOrigin=eyJpIjoiOTMzND... ) HHH-17020 ( https://hibernate.atlassian.net/browse/HHH-17020?atlOrigin=eyJpIjoiOTMzND... ) Can't use enum as string in join column when field is part of composite primary key ( https://hibernate.atlassian.net/browse/HHH-17020?atlOrigin=eyJpIjoiOTMzND... )
Issue Type: Bug Affects Versions: 6.3.0.CR1, 6.2.7, 6.2.8 Assignee: Unassigned Components: hibernate-core Created: 01/Aug/2023 08:45 AM Environment: Hibernate: 6.2.8-SNAPSHOT
initially found with Postgresql: 14.5
reproduced with h2 2.1.214
Spring Data JPA: 3.0.6
Spring Boot: 3.0.7
ehcache 3.10.8
JDK: OpenJDK 64-Bit Server VM Temurin-17.0.6
OS: Fedora 38 Priority: Major Reporter: Erwan Moutymbo ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=640210c... )
Hello, I'm migrating from hibernate 5.6.15 to hibernate 6.2 and I have noticed some issues. it seems that I can’t use an enum as a string with `@Enumerated( STRING )` when my enum is part of a composite primary key which itself is reference another composite primary key.
--------
Entities
--------
Product
-------
@Getter
@IdClass(ProductPK.class)
@EqualsAndHashCode(onlyExplicitlyIncluded = true )
@ToString(onlyExplicitlyIncluded = true )
@NoArgsConstructor(access = PROTECTED)
@Entity
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@DynamicUpdate
@Cacheable
@Cache(usage = READ_WRITE)
@Table(name = "PRODUCTS" )
public class Product {
public Product( String productId, Operator operator ) {
this.productId = productId;
this. operator = operator ;
}
public Product( String productId, Operator operator , Benefits benefits) {
this.productId = productId;
this. operator = operator ;
this.benefits = benefits;
}
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Column(name = "PRODUCT_ID" , nullable = false )
private String productId;
@Id
@EqualsAndHashCode.Include
@ToString.Include
@Getter
@Setter
@Cache(usage = READ_WRITE)
@ManyToOne(fetch = LAZY, optional = false )
@JoinColumn(name = "OPERATOR_ID" , nullable = false )
@JoinColumn(name = "COUNTRY" , nullable = false , columnDefinition = "varchar" )
private Operator operator ;
@Column(name = "DESCRIPTION" )
@Setter
private String description;
@Embedded
private Benefits benefits;
@EqualsAndHashCode
@ToString
@Embeddable
@NoArgsConstructor(access = PROTECTED)
public static class ProductPK implements Serializable {
private String productId;
@Embedded
private Operator.OperatorPK operator ;
public ProductPK( String productId, Operator.OperatorPK operator ) {
this.productId = productId;
this. operator = operator ;
}
public ProductPK( String productId, String operatorID, Country country) {
this.productId = productId;
this. operator = new Operator.OperatorPK(operatorID, country);
}
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class Benefits {
@Embedded
@NonFinal
@Setter
TypeOneBenefit credit;
@Embedded
@NonFinal
@Setter
TypeTwoBenefit data;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class TypeOneBenefit {
@NonFinal
@Column(name = "BENEFIT_ONE_BASE_AMOUNT" )
BigDecimal baseAmount;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class TypeTwoBenefit {
@NonFinal
@Column(name = "BENEFIT_TWO_BASE_AMOUNT" )
String baseAmount;
}
}
Operator
--------
@Getter
@Entity
@ToString(onlyExplicitlyIncluded = true )
@EqualsAndHashCode(onlyExplicitlyIncluded = true )
@NoArgsConstructor(access = PROTECTED)
@Table(name = "OPERATORS" )
@IdClass(Operator.OperatorPK.class)
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@DynamicUpdate
@Cacheable
@Cache(usage = READ_WRITE)
public class Operator {
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Enumerated(STRING)
@Column(name = "COUNTRY" , nullable = false , columnDefinition = "varchar" )
private Country country;
@EqualsAndHashCode.Include
@ToString.Include
@Id
@Column(name = "OPERATOR_ID" , nullable = false )
private String operatorId;
@ManyToOne
@JoinColumn(name = "meta_operator_id" , referencedColumnName = "ID" )
private MetaOperator metaOperator;
@OneToMany(mappedBy = " operator " , cascade = { CascadeType.ALL }, orphanRemoval = true , fetch = FetchType.LAZY)
private List<Product> products = new ArrayList<>();
public Operator( String operatorId) {
this.operatorId = operatorId;
// default country
this.country = USA;
}
public void setMetaOperator(MetaOperator metaOperator) {
this.metaOperator = metaOperator;
}
public void setProducts(List<Product> products) {
this.products = products;
}
@Embeddable
@Value
@AllArgsConstructor
@NoArgsConstructor(access = PROTECTED)
public static class OperatorPK implements Serializable {
@NonFinal
String operatorId;
@NonFinal
@Enumerated(STRING)
Country country;
}
}
note :
At first, I did not specify `columnDefinition = "varchar"` on Operator nor Product but I would get
Error executing DDL "create table operators (country clob not null check (country in ('USA','FRA')), meta_operator_id varchar(255), operator_id varchar(255) not null, primary key (country, operator_id))" via JDBC [Fonctionnalité non supportée: "Index on column: ""COUNTRY"" CHARACTER LARGE OBJECT NOT NULL"
Feature not supported: "Index on column: ""COUNTRY"" CHARACTER LARGE OBJECT NOT NULL";]
even though I had @Enumerated(STRING) on Operator.country
Country
-------
public enum Country {
USA,
FRA;
}
-----
Tests
-----
addProductTest
--------------
@Test
void addProductTest() {
String string = "ID" ;
String operatorID = "operatorID" ;
ProductPK id = new ProductPK(string, operatorID, USA);
String test = "test" ;
Operator operator = new Operator(operatorID);
operatorService.addOperator( operator );
Product product = new Product(string, operator );
product.setDescription(test);
productService.addProduct(product);
Optional<Product> byId = productService.getProduct(id);
assertThat(byId.orElseThrow().getDescription()).isEqualTo(test);
Optional<Product> byId2 = productService.readProduct(id);
assertThat(byId2.orElseThrow().getOperator().getOperatorId()).isEqualTo(operatorID);
}
an exception occurs when productService.addProduct(product); is committed :
at com.example.demo.service.ProductService$$SpringCGLIB$$0.addProduct(<generated>)
at com.example.demo.service.ProductServiceTest.addProductTest(ProductServiceTest.java:43)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Caused by: jakarta.persistence.RollbackException: Error while committing the transaction
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:65)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:561)
... 80 more
Caused by: java.lang.ClassCastException: class java.lang.Byte cannot be cast to class java.lang.String (java.lang.Byte and java.lang.String are in module java.base of loader 'bootstrap')
at org.hibernate.type.descriptor.java.StringJavaType.unwrap(StringJavaType.java:27)
at org.hibernate.type.descriptor.jdbc.VarcharJdbcType$1.doBind(VarcharJdbcType.java:108)
...
... 81 more
shouldDeleteOperator
--------------------
@Test
@Order(2)
void shouldDeleteOperator() {
// Given
String operatorID = "operatorID2" ;
Operator operator = new Operator(operatorID);
operatorDao.save( operator );
// When
operatorService.deleteOperator( new Operator.OperatorPK(operatorID, USA));
//Then
Optional<Operator> byId2 = operatorService.getOperator(operatorID);
assertThat(byId2).isEmpty();
}
this one fails when committing the transaction for operatorService.deleteOperator
org.springframework.dao.DataIntegrityViolationException: could not execute statement [Erreur lors de la conversion de données "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"
Data conversion error converting "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"; SQL statement:
delete from operators where country=? and operator_id=? and meta_operator_id is null [22018-214]] [delete from operators where country=? and operator_id=? and meta_operator_id is null]; SQL [delete from operators where country=? and operator_id=? and meta_operator_id is
...
Caused by: org.hibernate.exception.DataException: could not execute statement [Erreur lors de la conversion de données "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"
Data conversion error converting "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"; SQL statement:
delete from operators where country=? and operator_id=? and meta_operator_id is null [22018-214]] [delete from operators where country=? and operator_id=? and meta_operator_id is null]
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:53)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:56)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
...
... 80 more
Caused by: org.h2.jdbc.JdbcSQLDataException: Erreur lors de la conversion de données "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"
Data conversion error converting "'USA' (PRODUCTS: ""OPERATOR_ID"" TINYINT NOT NULL)"; SQL statement:
delete from operators where country=? and operator_id=? and meta_operator_id is null [22018-214]
-------
Sources
-------
source code can be found in branch cant_use_enum_as_string_in_join_columns : https://github.com/emouty/hibernate-issues/tree/cant_use_enum_as_string_i...
for information all the tests in OperatorServiceTest , ProductServiceTest , ProductServiceWithCacheTest are failing.
( https://hibernate.atlassian.net/browse/HHH-17020#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-17020#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100233- sha1:b4f309b )
10 months, 2 weeks
[JIRA] (HHH-17013) Parameter nullability check throws error
by Ilya Ryzhov (JIRA)
Ilya Ryzhov ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5f65f49... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiYTFkYzQ1MjI1... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-17013?atlOrigin=eyJpIjoiYTFkYz... ) HHH-17013 ( https://hibernate.atlassian.net/browse/HHH-17013?atlOrigin=eyJpIjoiYTFkYz... ) Parameter nullability check throws error ( https://hibernate.atlassian.net/browse/HHH-17013?atlOrigin=eyJpIjoiYTFkYz... )
Change By: Ilya Ryzhov ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5f65f49... )
Entity class:
{noformat}@Entity
@Table(name = "human_table")
class HumanEntity(
@Id
@GeneratedValue(generator = "human_id_seq")
@SequenceGenerator(name = "human_id_seq", sequenceName = "human_id_seq", allocationSize = 1)
@Column(name = "id")
val id: Int? = null,
@Column(name = "name")
var name: String? = null,
@Column(name = "gender")
var gender: Gender? = null
)
enum class Gender {
MALE, FEMALE
}{noformat}
Repository methods with HQL:
{noformat}interface HumanEntityRepository : JpaRepository<HumanEntity, Int> {
@Query("select he from HumanEntity he where :names is null or he.name in :names ")
fun findByNames(names: List<String>?): List<HumanEntity>
@Query("select he from HumanEntity he where :genders is null or he.gender in :genders ")
fun findByGender(genders: List<Gender>?): List<HumanEntity>
}
{noformat}
Calling {{humanEntityRepository.findByGender(listOf(Gender.MALE, Gender.FEMALE))}} produces
{noformat}java.lang.ClassCastException: class java.util.Arrays$ArrayList cannot be cast to class java.lang.Enum (java.util.Arrays$ArrayList and java.lang.Enum are in module java.base of loader 'bootstrap')
at org.hibernate.type.descriptor.converter.internal.OrdinalEnumValueConverter.toRelationalValue(OrdinalEnumValueConverter.java:23)
at org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:320)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:358)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:268)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:244)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:518)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367)
at org.hibernate.query.Query.getResultList(Query.java:119)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:148)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
at jdk.proxy2/jdk.proxy2.$Proxy214.findByGender(Unknown Source){noformat}
Calling {{humanEntityRepository.findByNames(listOf("Alice", "Bob"))}} produces
{noformat}Caused by: org.hibernate.HibernateException: Unknown wrap conversion requested: java.util.Arrays$ArrayList to java.lang.String : `org.hibernate.type.descriptor.java.StringJavaType` (java.lang.String)
at org.hibernate.type.descriptor.java.JavaTypeHelper.unknownWrap(JavaTypeHelper.java:24)
at org.hibernate.type.descriptor.java.AbstractClassJavaType.unknownWrap(AbstractClassJavaType.java:116)
at org.hibernate.type.descriptor.java.StringJavaType.wrap(StringJavaType.java:103)
at org.hibernate.type.descriptor.java.StringJavaType.coerce(StringJavaType.java:121)
at org.hibernate.type.descriptor.java.StringJavaType.coerce(StringJavaType.java:27)
at org.hibernate.query.internal.QueryParameterBindingImpl.coerce(QueryParameterBindingImpl.java:145)
at org.hibernate.query.internal.QueryParameterBindingImpl.setBindValue(QueryParameterBindingImpl.java:112)
at org.hibernate.query.spi.AbstractCommonQueryContract.setParameter(AbstractCommonQueryContract.java:825)
at org.hibernate.query.spi.AbstractSelectionQuery.setParameter(AbstractSelectionQuery.java:775)
at org.hibernate.query.sqm.internal.QuerySqmImpl.setParameter(QuerySqmImpl.java:1237)
at org.hibernate.query.sqm.internal.QuerySqmImpl.setParameter(QuerySqmImpl.java:129)
at org.springframework.data.jpa.repository.query.QueryParameterSetter$BindableQuery.setParameter(QueryParameterSetter.java:326)
at org.springframework.data.jpa.repository.query.QueryParameterSetter$NamedOrIndexedQueryParameterSetter.lambda$setParameter$4(QueryParameterSetter.java:117)
at org.springframework.data.jpa.repository.query.QueryParameterSetter$ErrorHandling$1.execute(QueryParameterSetter.java:140)
at org.springframework.data.jpa.repository.query.QueryParameterSetter$NamedOrIndexedQueryParameterSetter.setParameter(QueryParameterSetter.java:117)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:83)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:75)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:97)
at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:106)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:234)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:148)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 80 more
{noformat}
Swapping the order of nullability check to {{select he from HumanEntity he where he.name in :names or :names is null}} and calling {{humanEntityRepository.findByNames(listOf("Alice", "Bob"))}}results in
{noformat}java.lang.AssertionError
at org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:275)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:358)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:268)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:244)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:518)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367)
at org.hibernate.query.Query.getResultList(Query.java:119)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:148)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
at jdk.proxy2/jdk.proxy2.$Proxy233.findByNames(Unknown Source){noformat}
{{humanEntityRepository.findByNames(emptyList())}} results in
{noformat}java.util.NoSuchElementException
at kotlin.collections.EmptyIterator.next(Collections.kt:20)
at kotlin.collections.EmptyIterator.next(Collections.kt:15)
at org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:267)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:358)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:268)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:244)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:518)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367)
at org.hibernate.query.Query.getResultList(Query.java:119)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:92)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:148)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
at jdk.proxy2/jdk.proxy2.$Proxy228.findByNames(Unknown Source){noformat}
But querying the same HQL with a list of single element works fine.
( https://hibernate.atlassian.net/browse/HHH-17013#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-17013#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100233- sha1:b4f309b )
10 months, 2 weeks