为什么我要将此 "Repeated column in mapping for entity" 获取到 Hibernate 实体中?处理这种情况的最佳方法是什么?
Why am I obtaining this "Repeated column in mapping for entity" into an Hibernate entity? What is the best way to handle this situation?
我不太喜欢 Hibernate,我有以下 problem\doubt。
我有这种情况:
1) 我有这个 Room 实体 class 代表住宿的房间:
@Entity
@Table(name = "room")
public class Room implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne
@JoinColumn(name = "id_accomodation_fk", nullable = false)
private Accomodation accomodation;
@ManyToOne
@JoinColumn(name = "id_room_tipology_fk", nullable = false)
private RoomTipology roomTipology;
@OneToMany(mappedBy = "room")
private List<RoomMedia> roomMediaList;
@Column(name = "room_number")
private String number;
@Column(name = "room_name")
private String name;
@Column(name = "room_description")
private String description;
@Column(name = "is_enabled")
private Boolean isEnabled;
........................................................................
........................................................................
GETTER AND SETTER METHODS
........................................................................
........................................................................
}
2) 然后我有这个 RoomMedia 实体 class 表示与特定 Room 实体相关的照片:
@Entity
@Table(name = "room_media")
public class RoomMedia {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "id_room")
private Long idRoom;
@ManyToOne
@JoinColumn(name = "id_room", nullable = false) // da rinominare anche sul DB in room_fk
private Room room;
@Lob
@Column(name = "media")
private byte[] media;
private String description;
........................................................................
........................................................................
GETTER AND SETTER METHODS
........................................................................
........................................................................
}
如您在前面的代码中所见,这 2 个实体 class 以这种方式 link 组合在一起:
一个Room实例表示一个特定的房间并包含其照片列表,这样:
@OneToMany(mappedBy = "room")
private List<RoomMedia> roomMediaList;
这意味着一个房间被 link 编辑到许多 RoomMedia 实例。 mappedBy = "room" 表示要在 Room 和 RoomMedia 之间执行 link 使用 room RoomMedia 实体的 字段(表示 RoomMedia 实例的特定房间)。
然后在 RoomMedia 实体 class 我有这个 link:
@ManyToOne
@JoinColumn(name = "id_room", nullable = false)
private Room room;
Where 表示许多 RoomMedia 实例与单个 Room 实例相关。 Join 操作是使用 room_media table 上的 id_room 字段完成的(它在table 级别而不是实体级别)。
如果所有这些推理有问题,请更正。
我的问题是在应用程序启动时我收到了这条错误消息:
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1249)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access0(EntityManagerFactoryBuilderImpl.java:120)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:860)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
... 39 more
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.betrivius.domain.RoomMedia column: id_room (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:709)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:731)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:753)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:506)
at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1360)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1851)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:857)
... 48 more
为什么 Hibernate 不能处理两者?问题是什么?我该如何解决?
我认为这可能取决于在 RoomMedia 实例中我仍然有 id_room 字段的事实不再需要了,因为在这个实体中我也放了:
@ManyToOne
@JoinColumn(name = "id_room", nullable = false)
private Room room;
它本身包含这个 id。
所以我认为删除这个字段:
@Column(name = "id_room")
private Long idRoom;
我会解决我的问题,是吗?
但现在我可能会遇到另一个问题:在我的 DAO 中,我可能会有一些涉及 idRoom 的复杂查询。因此,为了方便起见,我会将 private Room room; 和 private Long idRoom; 字段都放入我的 RoomMedia实体class.
我怎样才能同时避免这个问题?
您绝对应该从映射中删除此列
@Column(name = "id_room")
private Long idRoom;
Hibernate 告诉你同样的事情。
But now I could will have another problem: into my DAO I could have some complex query that involves the idRoom. So, for convenience, I wold have both these private Room room; and private Long idRoom; field into my RoomMedia entity class.
正确的映射是
@ManyToOne
@JoinColumn(name = "id_room", nullable = false)
private Room room;
和它为您提供所需的一切
查询示例
Query query1 = em.createQuery("select rm from RoomMedia rm where rm.room.id = :id");
Query query2 = em.createQuery("select rm from RoomMedia rm join rm.room r where r.id = :id");
我不太喜欢 Hibernate,我有以下 problem\doubt。
我有这种情况:
1) 我有这个 Room 实体 class 代表住宿的房间:
@Entity
@Table(name = "room")
public class Room implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne
@JoinColumn(name = "id_accomodation_fk", nullable = false)
private Accomodation accomodation;
@ManyToOne
@JoinColumn(name = "id_room_tipology_fk", nullable = false)
private RoomTipology roomTipology;
@OneToMany(mappedBy = "room")
private List<RoomMedia> roomMediaList;
@Column(name = "room_number")
private String number;
@Column(name = "room_name")
private String name;
@Column(name = "room_description")
private String description;
@Column(name = "is_enabled")
private Boolean isEnabled;
........................................................................
........................................................................
GETTER AND SETTER METHODS
........................................................................
........................................................................
}
2) 然后我有这个 RoomMedia 实体 class 表示与特定 Room 实体相关的照片:
@Entity
@Table(name = "room_media")
public class RoomMedia {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "id_room")
private Long idRoom;
@ManyToOne
@JoinColumn(name = "id_room", nullable = false) // da rinominare anche sul DB in room_fk
private Room room;
@Lob
@Column(name = "media")
private byte[] media;
private String description;
........................................................................
........................................................................
GETTER AND SETTER METHODS
........................................................................
........................................................................
}
如您在前面的代码中所见,这 2 个实体 class 以这种方式 link 组合在一起:
一个Room实例表示一个特定的房间并包含其照片列表,这样:
@OneToMany(mappedBy = "room")
private List<RoomMedia> roomMediaList;
这意味着一个房间被 link 编辑到许多 RoomMedia 实例。 mappedBy = "room" 表示要在 Room 和 RoomMedia 之间执行 link 使用 room RoomMedia 实体的 字段(表示 RoomMedia 实例的特定房间)。
然后在 RoomMedia 实体 class 我有这个 link:
@ManyToOne
@JoinColumn(name = "id_room", nullable = false)
private Room room;
Where 表示许多 RoomMedia 实例与单个 Room 实例相关。 Join 操作是使用 room_media table 上的 id_room 字段完成的(它在table 级别而不是实体级别)。
如果所有这些推理有问题,请更正。
我的问题是在应用程序启动时我收到了这条错误消息:
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1249)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access0(EntityManagerFactoryBuilderImpl.java:120)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:860)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
... 39 more
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.betrivius.domain.RoomMedia column: id_room (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:709)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:731)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:753)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:506)
at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1360)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1851)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:857)
... 48 more
为什么 Hibernate 不能处理两者?问题是什么?我该如何解决?
我认为这可能取决于在 RoomMedia 实例中我仍然有 id_room 字段的事实不再需要了,因为在这个实体中我也放了:
@ManyToOne
@JoinColumn(name = "id_room", nullable = false)
private Room room;
它本身包含这个 id。
所以我认为删除这个字段:
@Column(name = "id_room")
private Long idRoom;
我会解决我的问题,是吗?
但现在我可能会遇到另一个问题:在我的 DAO 中,我可能会有一些涉及 idRoom 的复杂查询。因此,为了方便起见,我会将 private Room room; 和 private Long idRoom; 字段都放入我的 RoomMedia实体class.
我怎样才能同时避免这个问题?
您绝对应该从映射中删除此列
@Column(name = "id_room")
private Long idRoom;
Hibernate 告诉你同样的事情。
But now I could will have another problem: into my DAO I could have some complex query that involves the idRoom. So, for convenience, I wold have both these private Room room; and private Long idRoom; field into my RoomMedia entity class.
正确的映射是
@ManyToOne
@JoinColumn(name = "id_room", nullable = false)
private Room room;
和它为您提供所需的一切
查询示例
Query query1 = em.createQuery("select rm from RoomMedia rm where rm.room.id = :id");
Query query2 = em.createQuery("select rm from RoomMedia rm join rm.room r where r.id = :id");