Hibernate注解级联不起作用。

4
我决定使用Hibernate注解来改变hbm.xml的样式。 我的hbm.xml文件中原本有以下内容:
<hibernate-mapping package="by.sokol.jpr.data">
 <class name="Licence">
  <id name="licenceId">
   <generator class="native" />
  </id>
 <many-to-one name="user" lazy="false" cascade="save-update" column="usr"/>
 </class>
</hibernate-mapping>

然后将其更改为:

@Entity
public class Licence {

 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int licenceId;

 @ManyToOne(targetEntity=User.class, fetch=FetchType.EAGER, cascade = CascadeType.ALL)
 @Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE })
 private User user;
}

用户类:

@Entity(name = "Usr")
public class User {

    // BEGIN user info
    @Basic
    private String uid;
    @Basic
    private String name;
    @Basic
    private String company;
    @Basic
    private String street;

    // user's zip code
    @Basic
    private String ubication;
    @Basic
    private String city;
    @Basic
    private String po;

    @Column(name = "useremail")
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "assignedGen")
    @GenericGenerator(name = "assignedGen", strategy = "assigned")
    private String email;
    @Basic
    private String challengPassword;
    @Basic
    private String serialNumber;
}

Hibernate.cfg.xml

...
<mapping class="by.sokol.jpr.data.Licence" />
<mapping class="by.sokol.jpr.data.User" />
...

获取Session的Java代码

...
AnnotationConfiguration cfg = new AnnotationConfiguration();
cfg.configure(new File(PROPERTIES_FILENAME));
sessionFactory = cfg.buildSessionFactory();
...

保存许可证对象的Java代码

org.hibernate.Transaction t = session.beginTransaction();
session.saveOrUpdate(licence);
t.commit();

生成的SQL语句:

Hibernate: select this_.licenceId as licenceId0_2_, this_.creationDate as creation2_0_2_, this_.limitDate as limitDate0_2_, this_.user_useremail as user4_0_2_, this_.workstation_motherboardId as workstat5_0_2_, user1_.useremail as useremail1_0_, user1_.challengPassword as challeng2_1_0_, user1_.city as city1_0_, user1_.company as company1_0_, user1_.name as name1_0_, user1_.po as po1_0_, user1_.serialNumber as serialNu7_1_0_, user1_.street as street1_0_, user1_.ubication as ubication1_0_, user1_.uid as uid1_0_, workstatio4_.motherboardId as motherbo1_2_1_, workstatio4_.computerName as computer2_2_1_, workstatio4_.macAddress as macAddress2_1_, workstatio4_.osId as osId2_1_ from Licence this_ inner join Usr user1_ on this_.user_useremail=user1_.useremail left outer join Workstation workstatio4_ on this_.workstation_motherboardId=workstatio4_.motherboardId where user1_.useremail=?
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into Licence (creationDate, limitDate, user_useremail, workstation_motherboardId, licenceId) values (?, ?, ?, ?, ?)

追加_1:工作代码

org.hibernate.Transaction t = session.beginTransaction();
session.save(licence.getUser());
session.save(licence);
t.commit();

而且Hibernate在保存时不会保存用户信息。我真的需要帮助!


我只想指出应该拼写为“许可证”。 - Kevin Crowell
1
你是如何保存实体的?生成了什么SQL语句? - Robby Pond
2
@Kevin: "Licence"是英国的正常拼写方式。例如:http://www.tvlicensing.co.uk/ 美式英语的版本正在渐渐流行,就像许多其他美式拼写一样,但英式拼写是完全正确的。 - T.J. Crowder
添加了SQL请求数据和Java代码以保存对象。 - Denis
一切似乎都没问题。确保在保存时用户不为空。 - Bozho
显示剩余4条评论
2个回答

3

我建议除非你需要 delete-orphan,否则应该摆脱 @Cascade 注释。

仅使用 cascade = {CascadeType.MERGE, CascadeType.PERSIST}

另一件事要注意的是,你是否在使用 AnnotationConfiguration。如果不是,你的注释根本没有被解析。

更新:你确定你的用户设置了 email 字段吗?我建议为 User 的主键设置自动生成的 id。 email 是业务键,应该实现 hashCode()equals()


这是我第一次在stackoverflow上的经历,我喜欢它能够快速得到答案。根据回复,我可以补充以下内容: 1)cascade = {CascadeType.MERGE, CascadeType.PERSIST} - 我尝试过了,但没有成功。 - Denis
将其添加到您的问题中,而不是作为评论 - Bozho
抱歉,这是我第一次经历。我已经向我的问题中添加了信息。 - Denis

0

你的用户被定义为实体吗?不确定它是否与hbm和注释混合使用。 关系是双向的吗?也许你可以展示用户类?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接