[JIRA] (HHH-16908) Fail to compute
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=eyJpIjoiZGNjOTFkMmJm... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16908?atlOrigin=eyJpIjoiZGNjOT... ) HHH-16908 ( https://hibernate.atlassian.net/browse/HHH-16908?atlOrigin=eyJpIjoiZGNjOT... ) Fail to compute ( https://hibernate.atlassian.net/browse/HHH-16908?atlOrigin=eyJpIjoiZGNjOT... )
Issue Type: Bug Affects Versions: 6.2.6 Assignee: Unassigned Components: hibernate-core Created: 06/Jul/2023 08:45 AM Environment: Hibernate: tried 6.2.6.Final
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... )
I'm migrating from hibernate 5.6.15 to hibernate 6.2.5 and I have noticed some issues with my model. Hibernate seems to have difficulties to map a column.
--------
Entities
--------
@Getter
@Entity
@ToString(onlyExplicitlyIncluded = true )
@EqualsAndHashCode(onlyExplicitlyIncluded = true )
@IdClass(SpecialOperator.SpecialOperatorPK.class)
@Table(name = "SPECIAL_OPERATORS" )
@Cacheable
@Cache(usage = READ_WRITE)
@NoArgsConstructor(access = PROTECTED)
public class SpecialOperator {
@EqualsAndHashCode.Include
@ToString.Include
@Id
private Provider provider;
@EqualsAndHashCode.Include
@ToString.Include
@Id
private String operatorId;
@OneToMany(mappedBy = " operator " , cascade = { PERSIST, MERGE, REMOVE }, orphanRemoval = true )
private final Set<SpecialPricePoint> pricePoints = new HashSet<>();
@CreationTimestamp
@Column(name = "CREATION_DATE" , nullable = false , updatable = false )
private Instant creationDate;
@UpdateTimestamp
@Column(name = "MODIFICATION_DATE" , nullable = false )
private Instant modificationDate;
public void addPricePoint(SpecialPricePoint pricePoint) {
pricePoint.setOperator( this );
pricePoints.add(pricePoint);
}
public SpecialOperator(Provider provider, String operatorId) {
this.provider = provider;
this.operatorId = operatorId;
}
@EqualsAndHashCode
@ToString
@Getter
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
@Embeddable
public static class SpecialOperatorPK implements Serializable {
@Enumerated(EnumType.STRING)
@Column(name = "PROVIDER_ID" , nullable = false )
Provider provider;
@Column(name = "OPERATOR_ID" , nullable = false )
String operatorId;
}
}
@Getter
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true )
@ToString(onlyExplicitlyIncluded = true )
@Table(name = "SPECIAL_OPERATOR_PRICES_POINTS" )
@IdClass(SpecialPricePoint.SpecialPricePointPK.class)
@NoArgsConstructor(access = PROTECTED)
public class SpecialPricePoint {
public SpecialPricePoint(SpecialOperator operator ,
String wholesalePrice) {
this. operator = operator ;
this.wholesalePrice = wholesalePrice;
}
@ManyToOne
@ToString.Include
@Setter(PACKAGE)
@EqualsAndHashCode.Include
@JoinColumn(name = "PROVIDER_ID" , referencedColumnName = "PROVIDER_ID" )
@JoinColumn(name = "OPERATOR_ID" , referencedColumnName = "OPERATOR_ID" )
@MapsId
private SpecialOperator operator ;
@Column(name = "PRODUCT_ID" )
@Setter
private String productId;
@Id
@Column(name = "PRICE_POINT" , nullable = false )
@ToString.Include
@EqualsAndHashCode.Include
String wholesalePrice;
@OneToOne(cascade = { PERSIST, MERGE, REMOVE }, orphanRemoval = true )
@JoinColumn(name = "PRODUCT_ID" , referencedColumnName = "PRODUCT_ID" , updatable = false , insertable = false )
@JoinColumn(name = "PRICE_POINT" ,
referencedColumnName = "WHOLESALE_PRICE_AMOUNT" ,
updatable = false ,
insertable = false )
@JoinColumn(name = "OPERATOR_ID" , referencedColumnName = "OPERATOR_ID" , updatable = false , insertable = false )
@JoinColumn(name = "PROVIDER_ID" , referencedColumnName = "PROVIDER_ID" , updatable = false , insertable = false )
@Cache(usage = READ_WRITE)
private SpecialProduct product;
public void setProduct(SpecialProduct product) {
this.product = product;
this.productId = product.getProductId();
product.setWholesalePrice( this );
}
@Value
@Embeddable
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
public static class SpecialPricePointPK implements Serializable {
@Embedded
@NonFinal
@AttributeOverride(name = "provider" , column = @Column(name = "PROVIDER_ID" , nullable = false ))
@AttributeOverride(name = "operatorId" , column = @Column(name = "OPERATOR_ID" , nullable = false ))
SpecialOperatorPK operator ;
@NonFinal
String wholesalePrice;
}
}
@Getter
@EqualsAndHashCode(onlyExplicitlyIncluded = true )
@ToString(onlyExplicitlyIncluded = true )
@NoArgsConstructor(access = PROTECTED)
@Table(name = "SPECIAL_PRODUCTS" )
@Entity
@IdClass(SpecialProduct.SpecialProductPK.class)
@Cacheable
@Cache(usage = READ_WRITE)
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@DynamicUpdate
public class SpecialProduct {
public SpecialProduct( String productId,
SpecialPricePoint wholesalePrice) {
this.productId = productId;
this.wholesalePrice = wholesalePrice;
}
@Id
@EqualsAndHashCode.Include
@ToString.Include
@Column(name = "PRODUCT_ID" , nullable = false )
private String productId;
@Setter
@ToString.Include
@EqualsAndHashCode.Include
@OneToOne(optional = false , mappedBy = "product" )
@MapsId
private SpecialPricePoint wholesalePrice;
@CreationTimestamp
@Column(name = "CREATION_DATE" , nullable = false , updatable = false )
private Instant creationDate;
@OptimisticLock(excluded = true )
@UpdateTimestamp
@Column(name = "MODIFICATION_DATE" , nullable = false )
private Instant modificationDate;
@Value
@Embeddable
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor
public static class SpecialProductPK implements Serializable {
@Embedded
@NonFinal
@AttributeOverride(name = " operator.provider" , column = @Column(name = "PROVIDER_ID" , nullable = false ))
@AttributeOverride(name = " operator.operatorId" , column = @Column(name = "OPERATOR_ID" , nullable = false ))
@AttributeOverride(name = "wholesalePrice" , column = @Column(name = "WHOLESALE_PRICE_AMOUNT" , nullable = false ))
SpecialPricePointPK wholesalePrice;
@NonFinal
String productId;
}
}
----
Test
----
@Test
void shouldGetPricePoint() {
// given
String operatorId = "OPERATOR_1" ;
Provider provider = A;
SpecialOperator specialOperator = new SpecialOperator(provider, operatorId);
specialOperatorService.addOperator(specialOperator);
String wholesalePrice = "1 EUR" ;
// when
SpecialPricePoint specialPricePoint = new SpecialPricePoint(specialOperator, wholesalePrice);
specialPricePointService.addPricePoint(specialPricePoint);
// then
Optional<SpecialPricePoint> pricePoint = specialPricePointService.getPricePoint(provider, operatorId, wholesalePrice);
assertThat(pricePoint).isNotEmpty();
assertThat(pricePoint.orElseThrow().getWholesalePrice()).isEqualTo(wholesalePrice);
}
This test raised the following exception :
Caused by: org.hibernate.MappingException: bug in initComponentPropertyPaths
...
Caused by: org.hibernate.MappingException: broken column mapping for: _identifierMapper.wholesalePrice.id of: com.example.demo.local.special.SpecialProduct
...
GitHub repository with sources : https://github.com/emouty/hibernate-issues
( https://hibernate.atlassian.net/browse/HHH-16908#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16908#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#100230- sha1:e339e49 )
2 years, 9 months