我有@ManyToOne链接的实体。当我请求findByCity时,spring数据会“左外连接”。但是,如果我使用标准eq在hibernate上执行它 - 它会获得正常的请求,例如“select .... where city_id = ...”。 如何在没有@Query的情况下避免加入?
答案 0 :(得分:0)
默认情况下,使用@ManyToOne
关系的选择始终使用每个定义的联接。在Hibernate 5 Criteria中,您需要对其进行显式定义并为每个联接创建别名:
因此,不用写作(人->地址):
session.createCriteria(Person.class).
.add(Restrictions.eq("adress.serial", "42"));
我们需要写
session.createCriteria(Person.class).
.createAlias("adress", "adr");
.add(Restrictions.eq("adr.serial", "42"));
createAlias似乎不是完美的方法名称,因为这样做是:
加入关联,为加入的关联分配别名。
但是还有一种解决方法,如果您想简单地选择一个受 ID 限制且不受
我们可以使用adress_id
列代替上一个示例中的联接:
session.createCriteria(Person.class).
.add(Restrictions.eq("adressId", "42"));
如果您指定其他adressId
字段(仅用作Hibernate的映射信息),则此方法有效:
@Entity
@Access(AccessType.FIELD)
public class Person{
@Id
String id;
@JoinColumn(name = "adress_id")
@ManyToOne(fetch = FetchType.LAZY)
@Nullable
public Adress adress;
@Column(name = "adress_id", insertable = false, updatable = false)
private String adressId;
}
@Entity
@Access(FIELD)
public class Adress{
@Id
String id;
}
不需要AccessType.FIELD
(但是我们可以在示例中保留getter / setter)。 FetchType.LAZY
和@Nullable
也是可选的,但请在合理使用时明确说明。我们能够加载具有特定Person
的{{1}}个实体(我们知道地址ID)。但是我们不需要连接,因为在WHERE子句和初始获取(地址可以被延迟获取)中都不需要。