I work with EAP7 which contains Hibernate Core {5.0.9.Final-redhat-1}
I have two objects:
@Entity @Data @EqualsAndHashCode(callSuper = true, doNotUseGetters = true) @ToString(callSuper = true, doNotUseGetters = true) public class Keuze extends MainTable { @NonNull String naam; @Tolerate public Keuze() { } }
and
@Entity @Data @EqualsAndHashCode(callSuper = true, doNotUseGetters = true, exclude = {"gegeven", "werkJaar", "keuze", "keuzes" }) @ToString(callSuper = true, doNotUseGetters = true, exclude = { "gegeven", "werkJaar", "keuze", "keuzes" }) public class Waarde extends MainTable { @NonNull @ManyToOne(optional = false, fetch = FetchType.LAZY) Gegeven gegeven; @NonNull @ManyToOne(optional = false, fetch = FetchType.LAZY) WerkJaar werkJaar; String alfanumeriek; Integer numeriek; BigDecimal valuta; @Lob String tekst; Boolean polair; @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) Keuze keuze; @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE) Set<Keuze> keuzes; @Tolerate public Waarde() { } }
Both of them extend from this class:
@MappedSuperclass @Data @Cacheable public abstract class MainTable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Long id; @Version Long version; }
When calling merge on Waarde, this causes the following error:
Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [java.lang.Long vo.cjsm.monitoring.data.schema.dynamic.main.MainTable.id] by reflection for persistent property [vo.cjsm.monitoring.data.schema.dynamic.field.Keuze#id] : Keuze(super=MainTable(id=1, version=0), naam=Leesmotivatie) at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:43) at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:223) at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4601) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:148) at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:850) at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:832) at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:260) at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398) at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162) at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:431) at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:363) at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326) at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162) at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111) at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:468) at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:327) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69) at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:840) at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:822) at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:827) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1161) ... 149 more Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field vo.cjsm.monitoring.data.schema.dynamic.main.MainTable.id to java.lang.String at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58) at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36) at java.lang.reflect.Field.get(Field.java:393) at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39) ... 171 more
By removing the ToString line from Lombok and adding my own toString implementation, overriding the default value, the error message disappeared and the code works!
Now the object is as follows:
@Entity @Data @EqualsAndHashCode(callSuper = true, doNotUseGetters = true) public class Keuze extends MainTable { @NonNull String naam; @Tolerate public Keuze() { } @Override public String toString() { return getId().toString(); } }
So for some reason, for some unknown reason, the toString method affects how hibernation combines code ... Donโt ask me how :-) It seems to work. I tried everything else online with no luck!
Hope this helps someone else!