休眠/JPA 单向 OneToMany,在源表中具有常量值的连接条件

我想使用休眠注释来表示使用联接的单向一对多关系。我想要在连接上添加一个条件,以便仅当表中的列(“one”)等于常量值时才会发生这种情况。例如。

SELECT *
FROM buildings b
LEFT JOIN building_floors bf on bf.building_id = b.id AND b.type = 'OFFICE'

我想表示该查询的一部分。b.type = 'OFFICE'

我的问题与这个问题非常相似,除了我在源表上有一个条件。JPA/休眠连接在常量值上

Java 实体如下所示:

@Entity
@Table(name = "buildings")
public class Building {

    @Id
    @Column(name = "id")
    private int id;

    @Column(name = "type")
    private String type;

    @OneToMany(mappedBy = "buildingId",
            fetch = FetchType.EAGER,
            cascade = {CascadeType.ALL},
            orphanRemoval = true)
    @Fetch(FetchMode.JOIN)
    // buildings.type = 'OFFICE'   ????
    private Set<BuildingFloors> buildingFloors;

    // getters/setters
}

@Entity
@Table(name = "building_floors")
public class BuildingFloor {

    @Id
    @Column(name = "building_id")
    private int buildingId;

    @Id
    @Column(name = "floor_id")
    private int floorId;

    @Column(name = "description")
    private String description;

    // getters/setters
}

我已经尝试了一些有占位符注释的东西:

@Where注释

这不起作用,因为这适用于目标实体。

@JoinColumns注释

@JoinColumns({
        @JoinColumn(name = "building_id", referencedColumnName = "id"),
        @JoinColumn(name = "'OFFICE'", referencedColumnName = "type")
})

这不起作用,因为我得到以下错误(为清楚起见,进行了简化):Syntax error in SQL statement "SELECT * FROM buildings b JOIN building_floors bf on bf.building_id = b.id AND bf.'OFFICE' = b.type"

不同的@JoinColumns注释

@JoinColumns({
        @JoinColumn(name = "building_id", referencedColumnName = "id"),
        @JoinColumn(name = "buildings.type", referencedColumnName = "'OFFICE'")
})

这不起作用,因为当使用单向 OneToMany 关系时,引用的 ColumnnName 来自源表。所以我得到错误:org.hibernate.MappingException: Unable to find column with logical name: 'OFFICE' in buildings

提前致谢!


答案 1

为什么不使用继承? (我将其与JPA一起使用,我从不直接使用休眠)

@Entity
@Inheritance
@Table(name = "buildings")
@DiscriminatorColumn(name="type")
public class Building {

    @Id
    @Column(name = "id")
    private int id;

    @Column(name = "type")
    private String type;
}

和:

@Entity
@DiscriminatorValue("OFFICE")
public class Office extends Building {
    @OneToMany(mappedBy = "buildingId",
        fetch = FetchType.EAGER,
        cascade = {CascadeType.ALL},
        orphanRemoval = true)
    private Set<BuildingFloors> buildingFloors;
}

答案 2

通过以下选择创建数据库视图:

SELECT bf.* FROM building_floors bf JOIN buildings b on bf.building_id = b.id AND b.type = 'OFFICE'

将其作为普通实体映射到类,然后在类中使用它。OfficeBuildingFloors@OneToManyBuilding

当然,您将无法修改此类集合,也无法避免在 上使用的任何异常。@ImmutableOfficeBuildingFloors


推荐