知识点
相关文章
更多最近更新
更多hibernate中ManyToOne单向
2019-03-28 15:09|来源: 领悟书生
开始hibernate的关系映射,先来个多对一单向关系映射。例子是班级和学生之间的关系。
班级的实体和映射
Classroom.java
package org.zttc.itat.model; import java.util.Set; public class Classroom { private int id; private String name; private int grade; //set get 方法省去 }
Classroom.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.zttc.itat.model"> <class name="Classroom" table="t_cla"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <property name="grade"/> </class> </hibernate-mapping>
学生的实体和映射
Student.java
package org.zttc.itat.model; public class Student { private int id; private String name; private String no; private Classroom classroom; //set get 方法省去 }
Student.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.zttc.itat.model"> <class name="Student" table="t_stu"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <property name="no"/> <!-- many-to-one用来映射多对一,name表示对象中的属性名称 , column用来表示外键的名称--> <many-to-one name="classroom" column="cid"/> </class> </hibernate-mapping>
测试方法:
public class TestManyToOne { @Test public void testAdd01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); //先添加1 Classroom c = new Classroom(); c.setGrade(2012); c.setName("计算机网络技术"); session.save(c); Student stu1 = new Student(); stu1.setName("猪八戒"); stu1.setNo("001"); stu1.setClassroom(c); session.save(stu1); Student stu2 = new Student(); stu2.setName("孙悟空"); stu2.setNo("002"); stu2.setClassroom(c); session.save(stu2); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testAdd02() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); //先添加多 Student stu1 = new Student(); stu1.setName("沙僧"); stu1.setNo("003"); session.save(stu1); Student stu2 = new Student(); stu2.setName("唐僧"); stu2.setNo("004"); session.save(stu2); Classroom c = new Classroom(); c.setGrade(2012); c.setName("计算机应用技术"); session.save(c); //此时还会发两条update stu1.setClassroom(c); stu2.setClassroom(c); //最佳实践:一定要先添加一的一方,之后在添加多的一方 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testLoad() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Student stu = (Student)session.load(Student.class, 1); //此时仅仅只是发一条sql System.out.println(stu.getName()); //此时student的关联对象Classroom也是延迟加载的,会再发一条sql来取对象 System.out.println(stu.getClassroom().getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } }
如果在添加student的时候,Classroom
还没保存,就会出现抛异常如:
@Test public void testAdd03() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Classroom c = new Classroom(); c.setGrade(2012); c.setName("计算机信息管理"); //此时classroom没有存储,所以在添加student的时候没有外键,会抛出异常 Student stu1 = new Student(); stu1.setName("如来"); stu1.setNo("005"); session.save(stu1); Student stu2 = new Student(); stu2.setName("观音"); stu2.setNo("006"); session.save(stu2); stu1.setClassroom(c); stu2.setClassroom(c); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } }
这时我们可以添加级联(级联是指两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作)
修改Student.hbm.xml,在many-to-one加cascade属性
<!-- 当设置了cascade的时候,会自动完成关联,如果添加时没有关联对象,会自动创建一个关联对象 最佳实践:如果没有特殊情况不要使用cascade,特别注意,可能使用cascade的地方一般都是一的一方进行删除时使用,特殊需求才会使用cascade的add,正常情况add方法都是应该有程序员完成添加 --> <many-to-one name="classroom" column="cid" cascade="add"/>
对“
这句话解释一下,如果在多的一方设置级联删除,例如删除一个学生,也把一个班级给删了,但这个班级可能还有其他学生,所以删除的时候会出异常。所以如果要用,就用在一的一方。可能使用cascade的地方一般都是一的一方进行删除时使用
”
一般对<many-to-one>或<many-to-many>关联关系不设置级联(Cascade)操作
本文链接:hibernate中ManyToOne单向,由领悟书生原创(笔记),转载请注明出处http://www.656463.com/article/397
相关问答
更多-
有什么问题是以下几点: @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name="idEmployees") public List
getTasks() { return tasks; } 这有两个原因是错误的。 @JoinColumn(name="idEmployees")表示:使用名为idEmployees的连接列(即外键)映射此OneToMany。 但连接列未命名为idEmployees。 idEmployees是Employee ... -
尝试从过滤器定义中删除stock @Filter(name="stockDailyRecordFilter", condition="name = 'My stock'") 更新因此这里的股票是相关表而不是主表。 您可以尝试加入以使用IN进行子选择 condition="stock_id in (select id from stock where name = 'My stock')" Try to remove the stock from filter definition @Filter(nam ...
-
我将这个答案更好地解释,但请记住,这些都是hibernate映射的基础,你可以在任何在线教程中阅读它们。 用户表格是: userId userName etc 和车辆表 vehicleId userIdFK etc 它是一个显而易见的很多关系:一个用户更多的车辆。 为了映射这种关系,你有 @Entity class User { @Id private userId; private String userName // other code } 和 ...
-
是的,也可以为ManyToOne关系编制索引。 在大多数简单的情况下,你有一个实体,如Club标记为@Indexed ,然后你想索引它的一些字段,并通过相关实体Player @IndexedEmbedded属性嵌入 。 到目前为止,你做对了,这基本上为你的club指数定义了“扁平化”的架构。 问题是,在为player索引定义架构时,您将firstname标记为索引字段,但没有指示它将关系嵌入到playersClub 。 基本上你在这个属性上缺少@IndexedEmbedded 。 不要与@Contained ...
-
对于任何有类似问题的人,我通过改变解决了这个问题 /** * User who logged the work * * @ORM\ManyToMany(targetEntity="Application\Apps\Timesheet\Entity\User",cascade={"persist", "remove"}) * @ORM\JoinTable(name="timesheet_worklog_user", * joinColumns={@ORM\JoinColumn(name=" ...
-
如果关联是ManyToOne,则没有理由使用OneToOne,反之亦然。 使用适当的注释,它反映了关联的基数的真实性。 不这样做只会混淆应用程序的开发人员,如果不是Hibernate本身。 在数据库中,源的唯一性是否受限制并不会改变Hibernate的任何内容。 根据我的经验,Hibernate 确实在OneToOne的情况下创建了唯一的约束,如果没有,那么您应该创建它(我不会使用Hibernate创建模式,除非是快速的n肮脏的演示应用程序)。 但是,当然,如果存在唯一约束,并且您尝试使用相同的目标实体创建 ...
-
JPA规范(11.1.17) - EmbeddedId注释 EmbeddedId注释应用于实体类或映射超类的持久字段或属性,以表示一个可嵌入类的组合主键。 可嵌入类必须标注为Embeddable。[104] 不支持在嵌入式id类中定义的关系映射。 JPA规范(2.11.2) - 映射超类 被指定为映射超类的类可以以与实体相同的方式进行映射, 只不过映射将仅应用于其子类,因为映射超类本身不存在表 。 您不能在@Embeddable中将关系映射用作@EmbeddedId。 即使你在@MappedSuper类中有 ...
-
这个人可以拥有联盟或联盟的任务,这意味着任何时候任何一个人都将是空的。 因此,加入列上的可空值是真实的。 因此,你没有获得任务数据。 当您使用延迟加载时,单独针对特定任务的单独查询将被触发而无需加入联合表,当您调用person对象上的getMandates()时将返回结果。 The person can have mandate for either league or federation which means either one of them will be null at any point o ...
-
请找到下面的课程。 主要更改: http : //docs.oracle.com/javaee/6/api/javax/persistence/JoinColumn.html#nullable()指定以下行: nullable = false @JoinColumn(name = "deptno", referencedColumnName = "deptno", nullable = false) 这使得deptNo列不为null。 另外指定deptNo为非空列,所以它避免了不用dept数而保存empd ...
-
双向或单向ManyToOne doctrine2关联映射(bidirectional or unidirectional ManyToOne doctrine2 Association Mapping)[2022-06-23]
这一切都取决于你对这些实体的用途,但我认为如果文章知道哪些评论与其自身相关联而不是相反,那么它会更有用。 这样,您可以轻松地操作文章注释而无需使用存储库,或在树枝模板等中... 因为我不是真的很喜欢使用第三个表(使用OneToMany单向映射),其中实体两个表完成工作,我建议使用双向映射。 It all depends on the use you will have of those entities, but I think it's more useful if the article knows w ...