Пример использования
У меня есть сущность User, которая содержит карту UserProfiles, как вы можете видеть, UserProfile отображается как коллекция Element, а не как отдельная сущность.
@Entity
@Table(name = "user_")
public class User extends AbstractEntity<UserId> {
...
@ElementCollection
@CollectionTable(name = "user_profile")
@MapKey(name = "userProfileType")
@MapKeyEnumerated(STRING)
private Map<UserProfileType, UserProfile> userProfiles;
}
@Embeddable
@NoArgsConstructor(access = PACKAGE)
@AllArgsConstructor(staticName = "of")
@EqualsAndHashCode
public class UserProfile {
@Enumerated(STRING)
private UserProfileType userProfileType;
...
}
Примечание. Я использую Hibernate 5.2.14.
Проблема
Когда Hibernate обрабатывает эти сопоставления, я могу сделать следующее исключение:
Caused by: org.hibernate.AnnotationException: Associated class not found: UserProfile
at org.hibernate.cfg.annotations.MapBinder.bindKeyFromAssociationTable(MapBinder.java:168) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.cfg.annotations.MapBinder.access$000(MapBinder.java:66) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.cfg.annotations.MapBinder$1.secondPass(MapBinder.java:101) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1635) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1603) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:388) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
Обходные пути пробовали
Я попытался использовать @MapKeyColumn вместо @MapKey, но это вызвало еще одну ошибку, утверждающую, что физическое представление столбца user_profile_type уже существует.
Вопрос
Мне интересно, должно ли это работать в соответствии со спецификацией JPA?
Я думаю, это должно сработать, потому что я обнаружил очень похожую проблему, которая уже была исправлена в Hibernate 5: https://hibernate.atlassian.net/browse/HHH-5393
Спасибо за вашу помощь!
Ваше здоровье, Ласло
Кажется, не исправлено в Hibernate: hibernate.atlassian.net/browse/HHH-5393





Хотя я не работал над этим проектом в последнее время, я вижу, что проверил код в Git следующим образом через несколько дней после публикации вопроса в SoF.
@Entity
@Table(name = "user_")
public class User extends AbstractEntity<UserId> {
...
@ElementCollection
@CollectionTable(name = "user_profile")
@MapKeyColumn(name = "user_profile_type", insertable = false, updatable = false)
@MapKeyEnumerated(STRING)
private Map<UserProfileType, UserProfile> userProfiles;
...
}
@Embeddable
@NoArgsConstructor(access = PACKAGE)
@AllArgsConstructor(staticName = "of")
@EqualsAndHashCode
@ToString(of = {"userProfileType", "fullName"})
public class UserProfile {
@Enumerated(STRING)
@Column(name = "user_profile_type")
private UserProfileType userProfileType;
...
}
public enum UserProfileType {
FACEBOOK, GOOGLE;
}
Уловка, я думаю, должна была заключаться в добавлении insertable = false, updatable = false, и это устраняет ту ошибку, что user_profile_type уже был определен.
Я имею ту же самую проблему. Раздражающий.