今天使用JPA(Hibernate)实现一个一对一关联的时候,发现无法使用延迟加载.Person关联一个Picture.在读取Person的时候,显示的记载了对于的Picture.读取10个Person发生了11次数据库查询.
最后查阅资料后,发现是自己对OneToOne理解不够透彻所致.之前的关联是这么定义的.
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "Person
")
private Picture picture;
}
@Entity
public class Picture {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToOne
private Person Person;
}
主表是Picture,从表是Person.外键字段定义在Picture表中.在这种情况下.读取Person会现实的读取Picture.
因为如果延迟加载要起作用,就必须设置一个代理对象.但是Personn可以不关联一个Picture,如果有Picture关联就设置为代理对象延迟加载,如果不存在Picture就设置null,因为外键字段是定义在Picture表中的,Hibernate在不读取Picture表的情况是无法判断是否关联有Picture,因此无法判断设置null还是代理对象,统一设置为代理对象,也无法满足不关联的情况,所以无法使用延迟加载,只有显示读取Picture.
原因找到了.做了如下修改
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Picture picture;
}
@Entity
public class Picture {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToOne(mappedBy = "picture)
private Person Person;
}
修改了表的主从关系,这时外键字段定义在Personnel表中.Hibernate就可以在不读取Picture表的情况下根据外键字段设置null或者代理对象,延迟加载也就起作用了.
同样的道理,我们平时在使用一对多的情况是,多端是主表,因此可以通过外键字段判断进而设置代理对象或者null.而在一端,虽然Hibernate无法判断是否关联有对象.但是即使不关联对象时也不应该设置为null,而应该设置为一个空的List或者Map,那么Hibernate就可以通过代理这个List或者Map实现延迟加载.这也是为什么,我们在设置一端关联时,一般显式的new一个ArrayList或者HaskMap,如:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "personnel")
private List<Reward> rewards = new ArrayList<Reward>();
这就是为了避免使用null表示没有关联,和使用空的List一致.
分享到:
相关推荐
默认情况下,是懒加载(延迟加载),只有在真正需要时才会查询数据库。如果希望在加载主实体时同时加载关联实体,可以设置为`FetchType.EAGER`。 ### 四、实现实例 创建数据库表并进行数据填充后,我们可以通过...
默认情况下,关联对象可能会被立即加载(Eager Loading),但可以通过设置`fetch`属性为`FetchType.LAZY`实现懒加载(Lazy Loading),延迟到真正需要时才加载关联对象。 **六、查询与事务处理** 在业务逻辑中,...
如果想要延迟加载(LAZY),可以设置`fetch = FetchType.LAZY`。 8. **示例代码**: 下面是一个简单的代码示例,展示了如何在实际应用中创建和操作这些对象: ```java Session session = HibernateUtil....
在Java的持久化框架Hibernate中,懒加载(Lazy Loading)是一种重要的优化策略,它的核心思想是“延迟加载”或“按需加载”。默认情况下,当一个实体被加载时,并不会立即加载其关联的对象或集合,而是在真正需要...
此外,还可以设置`fetch`属性来控制加载策略,例如`FetchType.LAZY`表示延迟加载,只有在真正访问`profile`属性时才会加载关联的`Profile`对象。 除了显式定义外键外,还可以使用`@PrimaryKeyJoinColumns`注解,当...
- `fetch`:指定加载策略,如EAGER(即时加载)或LAZY(延迟加载)。 - `optional`:是否允许为null,如果为false,表示必须有对应的关联对象。 **四、元素的配置** 在XML配置文件中,元素的属性包括: - `name`:...
4. **fetch**:加载策略,FetchType.LAZY表示延迟加载,FetchType.EAGER表示立即加载。 5. **optional**:是否允许为null,true表示可以为null,false表示不能为空。 6. **mappedBy**:用于指定另一方的引用字段,...
如果希望延迟加载,可以使用`fetch=FetchType.LAZY`。 6. **级联操作** - 通过设置`cascade`属性,可以实现对象的级联操作,如保存、更新、删除等。这简化了数据库操作,使得操作一个对象时,其关联对象也会自动...
如果不需要立即加载,可以设置为`LAZY`,延迟加载关联实体。 4. **级联操作**:通过`CascadeType`可以设置级联操作,比如删除一个`Person`时,是否同时删除对应的`IdCard`。 在实际开发中,一对一关系映射的使用...
- **FetchType**: Hibernate的懒加载和立即加载策略,例如`FetchType.LAZY`和`FetchType.EAGER`,分别表示延迟加载和立即加载关联的对象。 - **InheritanceType**: Hibernate支持继承映射,如单表继承、联合继承和表...
2. **懒加载与立即加载**:使用`fetch`属性来决定关联对象是延迟加载(lazy)还是立即加载(eager)。 3. **非空性约束**:如果一方是必须的,可以通过`optional=false`来设置。 **七、总结** `hibernate_one_to_...
- `FetchType.LAZY` 或 `FetchType.EAGER`: 控制关联对象的加载策略,`LAZY`表示延迟加载,只有在需要时才加载关联对象;`EAGER`表示立即加载。 通过上述注解,我们可以轻松地在Java类中描述数据库表结构和对象关系...
- `fetch`属性:决定何时加载关联数据,`FetchType.LAZY`表示延迟加载,`FetchType.EAGER`表示立即加载。 - `cascade`属性:控制级联操作,如`CascadeType.ALL`表示所有操作都级联到关联对象。 - `unique`属性:...
默认是`LAZY`,延迟加载以提高性能。 - **Cascade类型**:`cascade`属性可以设置不同的级联操作,如`SAVE_UPDATE`、`DELETE`等,使得操作在一个实体上时自动影响相关实体。 - **OrphanRemoval**:通过`orphanRemoval...
- 使用`fetch = FetchType.LAZY`来延迟加载关联对象,只有在需要时才查询数据库。 - 使用`fetch = FetchType.EAGER`来立即加载关联对象,适合关联数据较小的情况。 - 适当使用`@Cacheable`和二级缓存,减少数据库...
- **懒加载(Lazy Loading)**:默认情况下,Hibernate 会延迟加载关联的对象,直到真正需要时才去数据库查询,以提高性能。 - **即时加载(Eager Loading)**:如果希望关联的对象在获取主对象时一起加载,可以设置...
- 使用`fetch`属性可以控制关联加载策略,如`EAGER`(立即加载)或`LAZY`(延迟加载)。 - `optional`属性默认为`true`,表示关联对象可以为`null`,设置为`false`则强制关联对象必须存在。 ### 示例代码 在给定的...
在实际应用中,我们可能还需要考虑性能优化,如使用延迟加载(lazy loading)来避免加载不必要的数据,或者根据业务需求调整级联策略。此外,测试也非常重要,确保关系映射在插入、更新和删除操作中能够正确工作。 ...
- `fetch`属性用于指定加载策略,`join`表示在查询时一起加载,`select`表示延迟加载。 - `property-ref`属性用于指定关联对象的属性名称。 - `access`属性定义了访问策略,可以是字段或属性访问。 - `formula`属性...