分享

JPA 一对一关联

 KILLKISS 2013-07-11
在一对一关联中,JPA没有规定谁为关系的维护方,OneToOne的mapped属性值指定了由另外一方实体的某个属性来维护一对一关联。以Person和IDCard为例。

Person类:
Java代码  收藏代码
  1. @Entity  
  2. @Table(name="pillow")  
  3. public class Person {  
  4.     private Integer id;  
  5.     private String name;  
  6.     private IDCard idcard;  
  7.     public Person() {  
  8.     }  
  9.     public Person(String name) {  
  10.         this.name = name;  
  11.     }  
  12.     @Id @GeneratedValue  
  13.     public Integer getId() {  
  14.         return id;  
  15.     }  
  16.     @Column(length=20, nullable=false)  
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.     @OneToOne(cascade={CascadeType.ALL},optional=false// optional specified to false means the corresponding column couldn't be nullable  
  21.     @JoinColumn(name="idcard_id"// Indicate the column name of the foreign key  
  22.     public IDCard getIdcard() {  
  23.         return idcard;  
  24.     }  
  25.     // Setters are omitted  
  26. }  


Java代码  收藏代码
  1. @Entity  
  2. public class IDCard {  
  3.     private Integer id;  
  4.     private String cardno;  
  5.     private Person person;  
  6.     public IDCard() {  
  7.     }  
  8.     public IDCard(String cardno) {  
  9.         this.cardno = cardno;  
  10.     }  
  11.     @Id @GeneratedValue  
  12.     public Integer getId() {  
  13.         return id;  
  14.     }  
  15.     @Column(length=18, nullable=false)  
  16.     public String getCardno() {  
  17.         return cardno;  
  18.     }  
  19.     // mappedBy specifies the property of the corresponding class that maintains the relationship. Also indicates this entity is the maintained edge.  
  20.     @OneToOne(mappedBy="idcard", cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.REFRESH},  
  21.             optional=false, fetch=FetchType.EAGER) // Maintained edge  
  22.     public Person getPerson() {  
  23.         return person;  
  24.     }  
  25.     // Setters are omitted  
  26. }  


1. 测试保存
Java代码  收藏代码
  1. public void save() {  
  2.     EntityManagerFactory factory = Persistence.createEntityManagerFactory("refrigerator");  
  3.     EntityManager em = factory.createEntityManager();  
  4.     Person person = new Person("Johnson");  
  5.     IDCard idcard = new IDCard("330818198602260444");  
  6.     // idcard.setPerson(person);  
  7.     person.setIdcard(idcard);  
  8.     em.getTransaction().begin(); // It's mandatory to open transaction to insert, update or delete data.  
  9.     em.persist(person);  
  10.     em.getTransaction().commit();  
  11.     em.close();  
  12.     factory.close();  
  13. }  


当IDCard的person属性的optional为true时,上面的idcard.setPerson(person)可以省略,因为Person既设置了级联属性cascade={CascadeType.ALL},在保存Person实体的时候也会保存IDcard,又是关系的维护方,在它们之间建立关联。如果为false,在先保存idcard时候,由于not null约束,程序报错。


2. 测试更新:
Java代码  收藏代码
  1. EntityManagerFactory factory = Persistence.createEntityManagerFactory("refrigerator");  
  2. EntityManager em = factory.createEntityManager();  
  3. em.getTransaction().begin();  
  4. IDCard idcard = em.find(IDCard.class1);  
  5. idcard.setCardno("330624198802060168");  
  6.         em.merge(idcard);  
  7. em.getTransaction().commit();  
  8. em.close();  
  9. factory.close();  

em.merge(idcard)可以省略,因为idcard已经是托管态了,对它的修改在commit的时候都会提交到数据库。如果idcard是游离态则需要该语句。


3. 测试查询:
Java代码  收藏代码
  1. public void queryFromMaintained() {  
  2.     EntityManagerFactory factory = Persistence.createEntityManagerFactory("refrigerator");  
  3.     EntityManager em = factory.createEntityManager();  
  4.     IDCard idcard = em.find(IDCard.class1);  
  5.     em.close();  
  6.     factory.close();  
  7.     System.out.println(idcard.getCardno());  
  8.     System.out.println(idcard.getPerson().getName());  
  9. }  

因为IDCard实体的person属性设置了fetch=FetchType.EAGER,jpa会使用一个SELECT连表查询出Person和IDCard。
如果fetch设置为FetchType.LAZY,jpa会使用两个SELECT语句(第一个查询出IDCard,第二个连表查询),不会产生EntityManager关闭导致的问题。


4. 测试删除:
Java代码  收藏代码
  1. public void deleteFromMaintained() {  
  2.     EntityManagerFactory factory = Persistence.createEntityManagerFactory("refrigerator");  
  3.     EntityManager em = factory.createEntityManager();  
  4.     em.getTransaction().begin();  
  5.     IDCard idcard = em.find(IDCard.class1);  
  6.     em.remove(idcard);  
  7.     em.getTransaction().commit();  
  8.     em.close();  
  9.     factory.close();  
  10. }  

当IDCard的person属性的optional为true时,能删除成功;为false时删除会报错:org.hibernate.PropertyValueException: not-null property references a null or transient value: com.john.bean.Person.idcard

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多