public class Foo {
private Long fooId;
private Bar bar;
//Yes, this doesn't actually make any sense,
//having both a list and a single object here, its an example.
private List<Bar> bars;
}
public class Bar {
private Long barId;
private Foo foo;
}
此外,我如何配置我的一对多用于孤立删除、惰性加载,以及在处理集合时是什么导致LazyInitialiaizationException
以及如何解决问题?
假设所有类都带有@entity
和@table
注释
单向一对一关系
public class Foo{
private UUID fooId;
@OneToOne
private Bar bar;
}
public class Bar{
private UUID barId;
//No corresponding mapping to Foo.class
}
foo.class管理的双向一对一关系
public class Foo{
private UUID fooId;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "barId")
private Bar bar;
}
public class Bar{
private UUID barId;
@OneToOne(mappedBy = "bar")
private Foo foo;
}
public class Foo{
private UUID fooId;
@OneToMany
@JoinTable(name="FOO_BAR",
joinColumns = @JoinColumn(name="fooId"),
inverseJoinColumns = @JoinColumn(name="barId"))
private List<Bar> bars;
}
public class Bar{
private UUID barId;
//No Mapping specified here.
}
@Entity
@Table(name="FOO_BAR")
public class FooBar{
private UUID fooBarId;
@ManyToOne
@JoinColumn(name = "fooId")
private Foo foo;
@ManyToOne
@JoinColumn(name = "barId")
private Bar bar;
//You can store other objects/fields on this table here.
}
public class Foo{
private UUID fooId;
@OneToMany(mappedBy = "bar")
private List<Bar> bars;
}
public class Bar{
private UUID barId;
@ManyToOne
@JoinColumn(name = "fooId")
private Foo foo;
}
public class Foo{
private UUID fooId;
@OneToMany
@JoinTable(name="FOO_BAR",
joinColumns = @JoinColumn(name="fooId"),
inverseJoinColumns = @JoinColumn(name="barId"))
private List<Bar> bars;
}
public class Bar{
private UUID barId;
@OneToMany
@JoinTable(name="FOO_BAR",
joinColumns = @JoinColumn(name="barId"),
inverseJoinColumns = @JoinColumn(name="fooId"))
private List<Foo> foos;
}
public class Foo{
private UUID fooId;
@OneToMany(mappedBy = "bar")
private List<FooBar> bars;
}
public class Bar{
private UUID barId;
@OneToMany(mappedBy = "foo")
private List<FooBar> foos;
}
@Entity
@Table(name="FOO_BAR")
public class FooBar{
private UUID fooBarId;
@ManyToOne
@JoinColumn(name = "fooId")
private Foo foo;
@ManyToOne
@JoinColumn(name = "barId")
private Bar bar;
//You can store other objects/fields on this table here.
}
默认情况下,Hibernate对集合使用惰性选择提取,对单值关联使用惰性代理提取。这些默认值对于大多数应用程序中的大多数关联都是有意义的。
当在对象上使用FetchType.lazy
和FetchType.Eage
时,请考虑这一点。如果您知道50%的情况下不需要访问父对象上的集合,那么我将使用fetchType.lazy
。
这样做的性能优势是巨大的,并且只会随着向集合中添加更多对象而增长。这是因为对于一个急切加载的集合,Hibernate会进行大量的幕后检查,以确保没有任何数据过期。虽然我确实提倡对集合使用Hibernate,但请注意,使用FetchType.Eager
存在性能损失**。但是,以我们的Person
对象为例。很可能,当我们加载人员
时,我们希望了解他们执行什么角色
。我通常会将此集合标记为FetchType.Eager
。不要仅仅为了绕过LazyInitializationException
而反射性地将集合标记为FetchType.Eager
。这不仅仅是因为性能原因,它通常表明您有设计问题。扪心自问,这个集合实际上应该是一个急切加载的集合,还是我这样做只是为了访问这个方法中的集合。Hibernate有解决这一问题的方法,它不会对操作的性能产生同样大的影响。如果您希望仅为这一次调用初始化缓慢加载的集合,则可以在service
层中使用以下代码。
//Service Class
@Override
@Transactional
public Person getPersonWithRoles(UUID personId){
Person person = personDAO.find(personId);
Hibernate.initialize(person.getRoles());
return person;
}
//DAO
@Override
public Person findPersonWithRoles(UUID personId){
Criteria criteria = sessionFactory.getCurrentSession().createCritiera(Person.class);
criteria.add(Restrictions.idEq(personId);
criteria.setFetchMode("roles", FetchMode.SUBSELECT);
}
public User saveOrUpdate(User user){
getCurrentSession.saveOrUpdate(user);
return user;
}
//Assume that user has no roles in the list, but has been saved to the
//database at a cost of 1 insert.
public void saveOrUpdateRoles(User user, List<Roles> listOfRoles){
for(Role role : listOfRoles){
role.setUser(user);
getCurrentSession.saveOrUpdate(role);
}
}
如果删除与对象的所有关联,Hibernate可以为您解决问题。假设您有一个用户
,他有一个角色
的列表,该列表中有5个不同角色的链接。假设您删除了一个名为ROLE_EXAMPLE>的角色
,但碰巧该ROLE_EXAMPLE>不存在于任何其他用户
对象上。如果在@OneTomany
批注上设置了orphanremove=true
,Hibernate将通过级联从数据库中删除现在为“孤立”的角色对象。
不应在每一种情况下都启用孤儿移除。事实上,在上面的示例中使用孤儿移除是没有意义的。仅仅因为没有用户
可以执行ROLE_EXAMPLE对象所表示的任何操作,这并不意味着任何未来的用户
将永远无法执行该操作。
这篇问答意在补充官方的Hibernate文档,该文档中有大量针对这些关系的XML配置。
问题内容: 我有两个课程,和,如下所示: 如何为这些类使用Hibernate 4的批注实现一个(单向/双向)一对多,多对一或多对多关系? 另外,我该如何配置我的一对多对象以移除孤儿,延迟加载以及在处理集合时会导致a的原因以及如何解决问题? 问题答案: 我有两个课程,和,如下所示: 创建带注释的关系 假定所有带有@Entity和注释的类@Table 单向一对一关系 由Foo.class管理的双向一对
问题是我写了简单的注释处理器,它根本不处理类型注释。simple annotations processor的源代码如下所示: 有什么想法如何使用或如何通过SimpleAnnotationsProcessor访问类型注释吗?使用可插入的注释处理API对我来说是不必要的,我认为它会比Java反射有更好的性能。无论如何,我也不知道如何通过Java反射访问类型注释。
问题内容: 我想获得应用程序中带有注释的类的完整列表。此操作的最佳机制是什么? ps。例如,JAX-RS实现如何找到所有带有注释的类?我想使用相同的机制。 问题答案: 通常,这是通过称为类路径扫描的过程完成的。通常,类加载器不允许扫描类路径上的所有类。但是通常唯一使用的类加载器是我们可以从中检索目录和jar文件的列表(请参阅getURLs),然后一个个地打开它们以列出可用的类。 这种方法由Scan
我在一个使用Selenium和C#的自动化项目中工作。我使用Page Object模式定义每个页面(带有它们的定位器),然后在一个测试类中分别定义测试。我有一个Page类,它是页面的基类,我在其中调用:PageFactory.initElements(webDriver,this); 并定义所有页面的通用方法。然后每个页面从page继承,并使用@findby注释定义相应的元素: 添加了一个新的登录
我需要创建一个对象,该对象包含一个表的所有字段,并且来自另一个表的一些信息在一起(不是全部)。 @查询(“从用户U内部加入U.Promotor P中选择new com.nowigo.systemsheet.User.User(U.id,U.name),其中P.id=?1”)公共列表findAllById(长promoterId); @查询(“从用户U内部加入U.P中选择U.id、U.name、P.
问题内容: 我目前正在创建一个有趣的python线性代数模块,并使用该语言进行实践。我最近尝试将类型注释添加到模块中,如下所示: 但是,当我尝试导入它时,它吐出一个。我承认这个问题已经在这里以某种形式得到了回答,但似乎并不能完全解决我的情况。 我想知道的是: 我已经在该文件中按字面值定义了该类。为什么说未定义名称? 如何定义可用于注释的方式(作为)? 问题答案: 您有一份前瞻性声明;函数(作为方法