Я работаю над проектом Gradle-Kotlin-Hibernate. Я хотел бы сохранить некоторые из моих классов неизменными, что особенно важно в Котлине. Это отлично работает для @Entity
@Entity(name = "SOMETHING") class MeetingKeychain( val immutableProp: String ) { // ID and others }
благодаря использованию плагина kotlin-jpa . Но тот же плагин не работает для @Embeddable .
@Embeddable class MeetingKeychain( val immutableProp: String ) { // ID and others }
Вызывается следующее исключение:
Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.component.PojoComponentTuplizer] at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:98) at org.hibernate.tuple.component.ComponentTuplizerFactory.constructDefaultTuplizer(ComponentTuplizerFactory.java:119) at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:64) at org.hibernate.mapping.Component.getType(Component.java:169) at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:398) at org.hibernate.mapping.Property.isValid(Property.java:225) at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:595) at org.hibernate.mapping.RootClass.validate(RootClass.java:265) at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:443) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ... 46 more Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:95) ... 56 more Caused by: org.hibernate.PropertyNotFoundException: Could not locate setter method for property [com.scherule.calendaring.domain.entities.ParticipantId#id] at org.hibernate.internal.util.ReflectHelper.findSetterMethod(ReflectHelper.java:540) at org.hibernate.property.access.internal.PropertyAccessBasicImpl.<init>(PropertyAccessBasicImpl.java:44) at org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl.buildPropertyAccess(PropertyAccessStrategyBasicImpl.java:27) at org.hibernate.mapping.Property.getGetter(Property.java:299) at org.hibernate.tuple.component.PojoComponentTuplizer.buildGetter(PojoComponentTuplizer.java:143) at org.hibernate.tuple.component.AbstractComponentTuplizer.<init>(AbstractComponentTuplizer.java:46) at org.hibernate.tuple.component.PojoComponentTuplizer.<init>(PojoComponentTuplizer.java:42) ... 61 more
Мой вопрос в том, что есть ли способ обойти это? Я бы хотел, чтобы мой класс @Embeddable был неизменным.
На самом деле это оказывается выполнимым и не связано с Котлином. Единственный способ, связанный с этим, заключается в том, что вам нужно создать конструктор по умолчанию, для которого используется этот плагин kotlin-jpa . Вы должны использовать
@Access(AccessType.FIELD)
в то время как
@Access(AccessType.PROPERTY)
по умолчанию. Затем он ищет сеттеры, а не использует полевые инъекции.