I updated from SpringBoot 2.7.6 to 3.0.0 to. Hibernate was updated from 5.6.14 to 6.1.5.
Update: 24.1.2023: I added a test case [https://github.com/git9999999/hibernate-test-case-templates/blob/main/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java|https://github.com/git9999999/hibernate-test-case-templates/blob/main/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java|smart-link]
but to me it is not clear where i have to put them in the Jira ticket.
I have the following Entities:
*OutboxMessage*
* *User* sentBy * *Address* sender
*User* (Could be *UserGuestPortal* or *UserMedicalExchange*) (Code see below)
*Address* (Could be *AddressGuestPortal* or *AddressMedicalExchange*)(Code see below) The Address has a referenz to UserGuestPortal and there is also a reference Back from AddressMedicalExchange to UserGuestPortal. Same applies for MedicalExchange
I can create and persit a OutboxMessage, with sentBy as a UserMedicalExchange and sender AddressMedicalExchange containing a UserMedicalExchange. When I load the OutboxMessage i see the following error Message MedicalExchange.
{noformat}org.hibernate.PropertyAccessException: Could not set value of type [com.rrr.health.medicalshare.domain.address.AddressGuestPortal] : com.rrr.health.medicalshare.domain.user.UserMedicalExchange.addressMedicalExchange (setter) at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:79) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:5074) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.initializeEntity(AbstractEntityInitializer.java:719) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.initializeInstance(AbstractEntityInitializer.java:652) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.sql.results.internal.domain.CircularBiDirectionalFetchImpl$CircularFetchAssembler.assemble(CircularBiDirectionalFetchImpl.java:282) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.sql.results.graph.DomainResultAssembler.assemble(DomainResultAssembler.java:33) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] at org.hibernate.metamodel.mapping.EntityMappingType.lambda$extractConcreteTypeStateValues$1(EntityMappingType.java:331) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final] {noformat}
When I debug, i see that Hibernate create a UserMedicalExchange instance and load data from the AddressGuestPortal into it, but this is wrong, it should be a AddressMedicalExchange. I did the Test with an empty Database, so there is not AddressGuestPortal anywhere around.
AbstractEntityPersister
!image-20230103-123254.png|width=945,height=666!
Tries to set the wrong Type of Address
!image-20230103-123306.png|width=848,height=459!
I checkout the open Bugs in Hibernate, but it seems i am the only one with this Problem, so i guess it the problem is on my side. :-(
{noformat}@Entity @Table(name = "T_OUTBOX_MESSAGE") public class OutboxMessage extends BaseEntity<OutboxMessageId> { ... @JsonIgnore @ManyToOne(fetch = FetchType.LAZY, cascade = {PERSIST, MERGE, REFRESH, DETACH}) @JoinColumn(name = "SENDER_ADDRESS_ID") private Address senderAddress; ... @JsonIgnore @OneToOne(fetch = FetchType.LAZY, cascade = {PERSIST, MERGE, REFRESH, DETACH}) @JoinColumn(name = "USER_ID") private User sentBy; {noformat}
{noformat}@Entity @Table(name = "T_USER") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "USER_TYPE", discriminatorType = DiscriminatorType.STRING) @Slf4j public abstract class User extends BaseEntity<UserId> implements DisplayNameGetter { {noformat}
{noformat}@Entity @DiscriminatorValue("USER_GUEST_PORTAL") public class UserGuestPortal extends User {
@OneToOne(cascade = {PERSIST, MERGE, REFRESH, DETACH}) @JoinColumn(name = "ADDRESS_ID") private AddressGuestPortal addressGuestPortal;{noformat}
{noformat}@Entity @DiscriminatorValue("USER_MEDICAL_EXCHANGE") public class UserMedicalExchange extends User { ... @JsonIgnore @OneToOne(cascade = {PERSIST, MERGE, REFRESH, DETACH}) @JoinColumn(name = "ADDRESS_ID", referencedColumnName = "ADDRESS_ID") private AddressMedicalExchange addressMedicalExchange;{noformat}
{noformat}@Entity @Table(name = "T_ADDRESS") @EntityListeners(AddressEntityListener.class) @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "ADDRESS_TYPE", discriminatorType = DiscriminatorType.STRING) @Slf4j public abstract class Address extends BaseEntity<AddressId> implements AddressValidateUserAccess, DisplayNameGetter {{noformat}
{noformat}@Entity @DiscriminatorValue("GUEST_PORTAL_USER") public class AddressGuestPortal extends Address {
@JsonIgnore @OneToOne(mappedBy = "addressGuestPortal", cascade = {PERSIST, MERGE, REFRESH, DETACH}) @JoinColumn(name = "address_id", referencedColumnName = "address_id") private final UserGuestPortal userGuestPortal = null;{noformat}
{noformat}@Entity @DiscriminatorValue("MEDICAL_EXCHANGE") public class AddressMedicalExchange extends Address {
@OneToOne(mappedBy = "addressMedicalExchange") private UserMedicalExchange userMedicalExchange;{noformat} |
|