我在两个类之间有一个相当简单的多对一关系:
@Entity
public class Schedule
implements java.io.Serializable {
private String scheduleName;
private HashSet<Step> steps;
@OneToMany(mappedBy="schedule", cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
public HashSet<Step> getSteps() {
return steps;
}
}
@Entity
public class Step implements java.io.Serializable {
private Long id;
private String duration;
private String stepType;
private Schedule schedule;
@ManyToOne(fetch=FetchType.LAZY)
public Schedule getSchedule() {
return schedule;
}
@Id
@GeneratedValue
public Long getId() {
return id;
}
}
Hibernate生成以下表格(在Postgres中)
Table "public.schedule"
Column | Type | Modifiers
--------------+------------------------+-----------
uuid | character varying(255) | not null
version | integer |
schedulename | character varying(255) |
steps | bytea |
Table "public.step"
Column | Type | Modifiers
---------------+------------------------+-----------
id | bigint | not null
duration | character varying(255) |
steptype | character varying(255) |
temperature | numeric(19,2) |
schedule_uuid | character varying(255) |
步骤表是我所期望的,但我不明白为什么步骤(bytea)列在那里。我在映射中做错了什么,或者我不明白hibernate是如何工作的?
答案 0 :(得分:6)
我怀疑问题是您使用的是具体的HashSet
而不是Set
界面。试试这个(假设某个地方有一个Id
):
@Entity
public class Schedule implements java.io.Serializable {
private String scheduleName;
private Set<Step> steps = new HashSet<Step>();
@OneToMany(mappedBy="schedule", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
public Set<Step> getSteps() {
return steps;
}
// other properties, getters, setters
}
还要注意我是如何初始化steps属性的。让我引用有关此内容的文档:
6.1. Persistent collections
...
注意实例变量是怎样的 用一个实例初始化 HashSet的。这是最好的方法 初始化集合值 新实例化的属性 (非持久性)实例。当你 使实例持久化 以persist()为例, Hibernate实际上会取代 带有实例的HashSet Hibernate自己实现的Set。
并确保:
@Id
属性(您展示的部分不足以确认)。Step
正在正确实施equals
/ hashCode
(请参阅下面的参考资料)。更新:无法重现(我没有安装PostgreSQL,我不认为它是相关的)。我使用了以下实体:
@Entity
public class Step implements java.io.Serializable {
private Long id;
private String duration;
private String stepType;
private Schedule schedule;
@ManyToOne(fetch = FetchType.LAZY)
public Schedule getSchedule() { return schedule; }
@Id @GeneratedValue
public Long getId() { return id; }
// getters, setters, equals, hashCode
}
和
@Entity
public class Schedule implements java.io.Serializable {
private Long id;
private String scheduleName;
private Set<Step> steps = new HashSet<Step>();
@OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Set<Step> getSteps() { return steps; }
@Id @GeneratedValue
public Long getId() { return id; }
// getters, setters
}
这是生成的DDL:
create table Schedule (
id bigint generated by default as identity (start with 1),
scheduleName varchar(255),
primary key (id)
)
create table Step (
id bigint generated by default as identity (start with 1),
duration varchar(255),
stepType varchar(255),
schedule_id bigint,
primary key (id)
)
alter table Step
add constraint FK277AEC7B775928
foreign key (schedule_id)
references Schedule
我甚至不明白你在HashSet
中如何使用OneToMany
,Hibernate在我尝试时抱怨(正如预期的那样诚实):
Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.stackoverflow.q4083744.Schedule.steps