JPA可能无效的外键映射
在实体上运行查询的问题
以及一个多对一的映射实体的属性,即可能是null的,也可能不是null的,即使映射多个对一的无效的记录,也不会返回记录实体可能符合搜索条件。这种行为似乎像是内在的联接而不是外部联接。
一切都适合CRUD操作,唯一的问题是在运行查询时。
预计
我希望这会像左外的连接一样行事,即使映射实体为无效,也可以返回匹配的记录。
期望与此类似的查询返回下面的两个属性记录,而仅返回预科书#10。
SELECT Property.* FROM Property
LEFT JOIN Resident ON Resident.id = Property.Resident_id
WHERE Property.Address LIKE "%test%" OR Resident.Name LIKE "%test%"
环境
- mysql v8
- eclipselink v2.7.7
桌子
属性
ID | 地址 | coldents_id |
---|---|---|
10 | 123测试Dr. | 20 |
11 | 456 Test St. | Null |
居民居民
ID | 名称 |
---|---|
10 | John Doe |
10 | John Williams |
Entities
Property Property Property Property
@Entity
@Table(name = "Property")
public class Property
{
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "Resident_id")
private Integer residentId;
@Column(name = "Address")
private String address;
@ManyToOne(optional = true, fetch = FetchType.LAZY)
@JoinColumn(name = "Resident_id", referencedColumnName = "id", updatable = false, insertable = false, nullable = true)
private Resident resident;
居民居民
@Entity
@Table(name = "Resident")
public class Resident
{
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "Name")
private String name;
查询
public List<Property> search(String str)
{
List<Property> list = new ArrayList<>();
if(str == null || str.isEmpty())
return list;
try
{
String sql = "SELECT x FROM Property x WHERE " +
" x.address LIKE :str OR x.resident.name LIKE :str" +
" ORDER BY x.address";
Query q = this.getEntityManager().createQuery(sql);
q.setParameter("str", "%"+str+"%");
list.addAll(q.getResultList());
}
catch(Exception e)
{
e.printStackTrace();
}
return list;
}
Problem
When running a query on an entity and an attribute of a many-to-one mapped entity, that may or may not be null, no records are returned on records where the mapped many-to-one is null, even if the main entity may match the search criteria. This behavior seems to be acting like an INNER JOIN instead of an OUTER JOIN.
Everything works fine for CRUD operations, the only problem is when the query is run.
Expected
I expect this to behave like a LEFT OUTER JOIN, and return records that match even if the mapped entity is null.
Expecting a query similar to this to return both property records below, when only preperty #10 is returned.
SELECT Property.* FROM Property
LEFT JOIN Resident ON Resident.id = Property.Resident_id
WHERE Property.Address LIKE "%test%" OR Resident.Name LIKE "%test%"
Environment
- MySQL v8
- Eclipselink v2.7.7
Tables
Property
id | Address | Resident_id |
---|---|---|
10 | 123 Test Dr. | 20 |
11 | 456 Test St. | null |
Resident
id | Name |
---|---|
10 | John Doe |
11 | James Williams |
Entities
Property
@Entity
@Table(name = "Property")
public class Property
{
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "Resident_id")
private Integer residentId;
@Column(name = "Address")
private String address;
@ManyToOne(optional = true, fetch = FetchType.LAZY)
@JoinColumn(name = "Resident_id", referencedColumnName = "id", updatable = false, insertable = false, nullable = true)
private Resident resident;
Resident
@Entity
@Table(name = "Resident")
public class Resident
{
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "Name")
private String name;
Query
public List<Property> search(String str)
{
List<Property> list = new ArrayList<>();
if(str == null || str.isEmpty())
return list;
try
{
String sql = "SELECT x FROM Property x WHERE " +
" x.address LIKE :str OR x.resident.name LIKE :str" +
" ORDER BY x.address";
Query q = this.getEntityManager().createQuery(sql);
q.setParameter("str", "%"+str+"%");
list.addAll(q.getResultList());
}
catch(Exception e)
{
e.printStackTrace();
}
return list;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
JPQL要求提供者对待”。路径表达为内在连接,因此呼叫X.Resident.Name将将空居民排除在选择之外。
您想要的更多是
JPQL requires providers to treat '.' path expressions as inner joins, so calling x.resident.name will exclude null residents from the selection.
What you want is more along the lines of