zoukankan      html  css  js  c++  java
  • Hibernate升级后注解方式的对象关系映射

    我要说的升级指的是我实际中遇到的,由于我之前的项目中Hibernate是3.3.2版本的,那时关于Annotation注解方式的对象关系映射得依赖这么几个包:

      hibernate-annotations.jar,

      ejb3-persistence.jar

      hibernate-commons-annotations.jar

    所以之前的项目如果更换为3.5.3版本后(当前最新发布的最终版本是3.6.0),那么这三个依赖包都会没有了,取而代之的是

    \hibernate-distribution-3.6.0.Final\lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar

    也就是说这个hibernate-jpa-2.0-api-1.0.0.Final.jar能够代替上面的三个包的作用

     

    先回顾下一个简单的注解方式的例子



     

    User.java

    Java代码  收藏代码
    1. <span style="font-size: large;">package com.javacrazyer.test;  
    2.   
    3. import javax.persistence.Column;  
    4. import javax.persistence.Entity;  
    5. import javax.persistence.GeneratedValue;  
    6. import javax.persistence.GenerationType;  
    7. import javax.persistence.Id;  
    8. import javax.persistence.Table;  
    9.   
    10. @Entity  
    11. @Table(name = "user")  
    12. // 非必要,在表格名称与类别名称不同时使用  
    13. public class User {  
    14.     @Id  
    15.     @GeneratedValue(strategy = GenerationType.AUTO)  
    16.     private Integer id;  
    17.   
    18.     @Column(name = "name")  
    19.     // 非必要,在字段名称与属性名称不同时使用  
    20.     private String name;  
    21.   
    22.     @Column(name = "age")  
    23.     private Integer age; // 非必要,在字段名称与属性名称不同时使用  
    24.   
    25.     // 必须要有一个预设的建构方法  
    26.     // 以使得Hibernate可以使用Constructor.newInstance()建立对象  
    27.     public User() {  
    28.     }  
    29.   
    30.     public Integer getId() {  
    31.         return id;  
    32.     }  
    33.   
    34.     public void setId(Integer id) {  
    35.         this.id = id;  
    36.     }  
    37.   
    38.     public String getName() {  
    39.         return name;  
    40.     }  
    41.   
    42.     public void setName(String name) {  
    43.         this.name = name;  
    44.     }  
    45.   
    46.     public Integer getAge() {  
    47.         return age;  
    48.     }  
    49.   
    50.     public void setAge(Integer age) {  
    51.         this.age = age;  
    52.     }  
    53. }  
    54. </span>  

    Category.java

    Java代码  收藏代码
    1. <span style="font-size: large;">package com.javacrazyer.test;  
    2.   
    3. import java.io.Serializable;  
    4. import java.util.ArrayList;  
    5. import java.util.List;  
    6.   
    7. import javax.persistence.CascadeType;  
    8. import javax.persistence.Entity;  
    9. import javax.persistence.FetchType;  
    10. import javax.persistence.GeneratedValue;  
    11. import javax.persistence.Id;  
    12. import javax.persistence.JoinColumn;  
    13. import javax.persistence.ManyToOne;  
    14. import javax.persistence.OneToMany;  
    15. import javax.persistence.Table;  
    16. import javax.persistence.Version;  
    17.   
    18.   
    19.   
    20. /** 
    21.  * 产品类别 
    22.  * 
    23.  */  
    24. @Entity  
    25. @Table(name="category")  
    26. public class Category implements Serializable{  
    27.     private static final long serialVersionUID = -3942148673242309324L;  
    28.     @Id  
    29.     @GeneratedValue  
    30.     private Integer id;  
    31.     @Version  
    32.     private Integer version;  
    33.     private String name;  
    34.     private String description;  
    35.     private String path;  //分类路径  
    36.   
    37.     //Category 自身双向多对一   
    38.     @ManyToOne(cascade={CascadeType.MERGE,CascadeType.PERSIST})  
    39.     private Category parent;  
    40.       
    41.     //Category 自身双向一对多   
    42.     @OneToMany(mappedBy="parent",fetch=FetchType.EAGER,cascade=CascadeType.ALL)  
    43.     @JoinColumn(name="parent_id")  
    44.     private List<Category> child = new ArrayList<Category>();  
    45.       
    46.       
    47.     public Integer getId() {  
    48.         return id;  
    49.     }  
    50.     public void setId(Integer id) {  
    51.         this.id = id;  
    52.     }  
    53.     public String getName() {  
    54.         return name;  
    55.     }  
    56.     public void setName(String name) {  
    57.         this.name = name;  
    58.     }  
    59.     public String getDescription() {  
    60.         return description;  
    61.     }  
    62.     public void setDescription(String description) {  
    63.         this.description = description;  
    64.     }  
    65.     public Category getParent() {  
    66.         return parent;  
    67.     }  
    68.     public void setParent(Category parent) {  
    69.         this.parent = parent;  
    70.     }  
    71.     public List<Category> getChild() {  
    72.         return child;  
    73.     }  
    74.     public void setChild(List<Category> child) {  
    75.         this.child = child;  
    76.     }  
    77.     public Integer getVersion() {  
    78.         return version;  
    79.     }  
    80.       
    81.     @SuppressWarnings("unused")  
    82.     private void setVersion(Integer version) {  
    83.         this.version = version;  
    84.     }  
    85.     public String getPath() {  
    86.         return path;  
    87.     }  
    88.     public void setPath(String path) {  
    89.         this.path = path;  
    90.     }  
    91. }</span>  

     hibernate.cfg.xml

    Java代码  收藏代码
    1. <span style="font-size: large;"><?xml version="1.0" encoding="utf-8" ?>  
    2. <!DOCTYPE hibernate-configuration PUBLIC  
    3.     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
    4.     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
    5.   
    6. <hibernate-configuration>  
    7. <session-factory>  
    8.        <!-- 显示实际操作数据库时的SQL -->   
    9.         <property name="show_sql">true</property>   
    10.         <!-- SQL方言,这边设定的是MySQL -->   
    11.         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>   
    12.         <!-- JDBC驱动程序 -->   
    13.         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>   
    14.         <!-- JDBC URL -->   
    15.         <property name="connection.url">jdbc:mysql:///test</property>   
    16.         <!-- 数据库使用者 -->   
    17.         <property name="connection.username">root</property>   
    18.         <!-- 数据库密码 -->   
    19.         <property name="connection.password">root</property>   
    20.         <property name="default_batch_fetch_size">10</property>  
    21.         <property name="hibernate.current_session_context_class">thread</property>  
    22.         <property name="show_sql">true</property>  
    23.         <property name="format_sql">true</property>  
    24.         <property name="hbm2ddl.auto">update</property>  
    25.         <!-- 以下设置对象与数据库表格映像类别 -->  
    26.         <mapping class="com.javacrazyer.test.User"/>  
    27.         <mapping class="com.javacrazyer.test.Category"/>    
    28. </session-factory>  
    29. </hibernate-configuration></span>  

    Hibernate工具类

    Java代码  收藏代码
    1. <span style="font-size: large;">package com.javacrazyer.common;  
    2.   
    3. import org.hibernate.Session;  
    4. import org.hibernate.SessionFactory;  
    5. import org.hibernate.cfg.AnnotationConfiguration;  
    6.   
    7. /** 
    8.  * Hibernate工具类 
    9.  *  
    10.  */  
    11. public class HibernateUtil {  
    12.     private static final SessionFactory factory;  
    13.       
    14.     private HibernateUtil(){}  
    15.       
    16.     static{  
    17.         //加载Hibernate全局配置文件,根据配置信息创建SessionFactory工厂实例  
    18.         factory = new AnnotationConfiguration().configure().buildSessionFactory();  
    19.     }  
    20.       
    21.     public static SessionFactory getSessionFactory(){  
    22.         return factory;  
    23.     }  
    24.       
    25.     /** 
    26.      * 本方法用来获取当前线程上绑定的Session实例 
    27.      * 注意hibernate全局配置文件中,如果使用是JDBC事务,添加如下配置:<br/> 
    28.      * <property name="hibernate.current_session_context_class">thread</property> 
    29.      * @return 
    30.      */  
    31.     public static Session getSession(){  
    32.         return factory.getCurrentSession();  
    33.     }  
    34. }  
    35. </span>  

     

    测试类

    Java代码  收藏代码
    1. <span style="font-size: large;">package com.javacrazyer.test;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. import org.hibernate.Session;  
    7. import org.hibernate.SessionFactory;  
    8. import org.hibernate.Transaction;  
    9. import org.junit.BeforeClass;  
    10. import org.junit.Test;  
    11.   
    12. import com.javacrazyer.common.HibernateUtil;  
    13.   
    14.   
    15. public class MyTest {  
    16.     private static SessionFactory sf;  
    17.   
    18.     @BeforeClass  
    19.     public static void init() {  
    20.         sf = HibernateUtil.getSessionFactory();  
    21.     }  
    22.   
    23.     @Test  
    24.     public void useradd() {  
    25.         User user = new User();  
    26.         user.setName("caterpillar");  
    27.         user.setAge(new Integer(30));  
    28.   
    29.         // 开启Session,相当于开启JDBC的Connection  
    30.         Session session = sf.getCurrentSession();  
    31.         // Transaction表示一组会话操作  
    32.         Transaction tx = session.beginTransaction();  
    33.         // 将对象映像至数据库表格中储存  
    34.         session.save(user);  
    35.         tx.commit();  
    36.   
    37.         System.out.println("新增资料OK!请先用MySQL观看结果!");  
    38.     }  
    39.       
    40.     @Test  
    41.     public void categoryadd(){  
    42.         Category category=new Category();  
    43.         category.setName("类别1");  
    44.           
    45.         Category category1=new Category();  
    46.         category1.setName("类别1-01");  
    47.         category1.setParent(category);  
    48.           
    49.         Category category2=new Category();  
    50.         category2.setName("类别1-02");  
    51.         category2.setParent(category);  
    52.           
    53.         List<Category> childs=new ArrayList<Category>();  
    54.         childs.add(category1);  
    55.         childs.add(category2);  
    56.         category.setChild(childs);  
    57.         Session session = sf.getCurrentSession();  
    58.         // Transaction表示一组会话操作  
    59.         Transaction tx = session.beginTransaction();  
    60.         session.persist(category);  
    61.         tx.commit();  
    62.     }  
    63.       
    64.       
    65.   
    66. }  
    67. </span>  

     

     

    对于User的持久化操作相当顺利,这个升级过程是成功的。

    但是对于Category的升级就没那么容易了,如果不细心发现的话,总是报

    Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn

    或者是Unrooted Test之类的错误
     
    错误发生在下面这些代码中
    @OneToMany(mappedBy="parent",fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    @JoinColumn(name="parent_id")
    private List<Category> child = new ArrayList<Category>();
    后来发现在3.5.3版本中@JoinColumn与mappingBy是互斥的,之前在hibernate.3.3.2中都是正确无误的,也就是hibernate.3.3.2允许这两个互相存在。所以呢,如果升级到hibernate3.5.3想测试成功的话,mappBy="parent",就应该去掉,正确的配置应该是这样
    @OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    @JoinColumn(name="parent_id")
    private List<Category> child = new ArrayList<Category>();
     
    索性将mappingBy再温习下
    a) 只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
    b) mappedBy标签一定是定义在the owned side(被拥有方的),他指向the owning side(拥有方);
    c) mappedBy的含义,应该理解为,拥有方能够自动维护 跟被拥有方的关系;
       当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以做到的。
    d) mappedBy跟JoinColumn/JoinTable总是处于互斥的一方,可以理解为正是由于拥有方的关联被拥有方的字段存在,拥有方才拥有了被 拥有方。mappedBy这方定义的JoinColumn/JoinTable总是失效的,不会建立对应的字段或者表
    明天你还会爱我?
  • 相关阅读:
    网络安全分析
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1540 机器
    java实现 洛谷 P1540 机器
  • 原文地址:https://www.cnblogs.com/eggbucket/p/2837786.html
Copyright © 2011-2022 走看看