spe*_*hak 3 java orm hibernate jpa
我在两个类之间有一个相当简单的多对一关系:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
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) |
Run Code Online (Sandbox Code Playgroud)
步骤表是我所期望的,但我不明白为什么步骤(bytea)列在那里.我在映射中做错了什么,或者我不明白hibernate是如何工作的?
我怀疑问题是你使用的是混凝土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
}
Run Code Online (Sandbox Code Playgroud)
另请注意我是如何初始化steps属性的.让我引用有关此内容的文档:
6.1.持久收藏
...
注意实例变量是如何使用HashSet实例初始化的.这是初始化新实例化(非持久)实例的集合值属性的最佳方法.当你使实例持久化时,通过调用persist()为例,Hibernate实际上会用Hibernate自己的Set实现替换HashSet.
并确保:
@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
}
Run Code Online (Sandbox Code Playgroud)
和:
@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
}
Run Code Online (Sandbox Code Playgroud)
这是生成的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
Run Code Online (Sandbox Code Playgroud)
我甚至不明白你怎么能HashSet在你的OneToManyHibernate抱怨中使用a (正如我所预料的那样):
Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.stackoverflow.q4083744.Schedule.steps
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13061 次 |
| 最近记录: |