JPA可能无效的外键映射

发布于 2025-02-04 05:50:06 字数 2557 浏览 2 评论 0原文

在实体上运行查询的问题

以及一个多对一的映射实体的属性,即可能是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
10123测试Dr.20
11456 Test St.Null

居民居民

ID名称
10John Doe
10John 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

idAddressResident_id
10123 Test Dr.20
11456 Test St.null

Resident

idName
10John Doe
11James 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

记忆消瘦 2025-02-11 05:50:06

JPQL要求提供者对待”。路径表达为内在连接,因此呼叫X.Resident.Name将将空居民排除在选择之外。

您想要的更多是

String JPQL = "SELECT x FROM Property x left join x.resident resident " +
                "WHERE x.address LIKE :str OR resident.name LIKE :str" +
                " ORDER BY x.address";

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

String JPQL = "SELECT x FROM Property x left join x.resident resident " +
                "WHERE x.address LIKE :str OR resident.name LIKE :str" +
                " ORDER BY x.address";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文