Java 如何使用JPA和Hibernate连接非主键上的表

Java 如何使用JPA和Hibernate连接非主键上的表,java,hibernate,jpa,orm,hibernate-mapping,Java,Hibernate,Jpa,Orm,Hibernate Mapping,我有3种型号User,House,UserHouseMap。我需要通过地图进入用户的房子。唯一的问题是这是一个旧的数据库&我无法更改我需要使用非主键User.name将User映射到UserHouseMap Hibernate不断给我错误,说我需要将其作为主键,或者我收到错误,说发生了JPA错误(无法构建EntityManagerFactory):在org.Hibernate.mapping.Table(用户)及其相关的超级表和辅助表中找不到逻辑名为name的列 我尝试了@Formula作为一种

我有3种型号
User
House
UserHouseMap
。我需要通过地图进入用户的房子。唯一的问题是这是一个旧的数据库&我无法更改我需要使用非主键
User.name
User
映射到
UserHouseMap

Hibernate不断给我错误,说我需要将其作为主键,或者我收到错误,说发生了JPA错误(无法构建EntityManagerFactory):在org.Hibernate.mapping.Table(用户)及其相关的超级表和辅助表中找不到逻辑名为name的列

我尝试了
@Formula
作为一种解决方法,但没有成功。我也试过
@JoinColumnOrFormula
,但也没用。这是我用
@公式

@Expose
@ManyToOne(targetEntity = House.class)
@Formula("(select * from houses inner join user_house_map on houses.house_name = user_house_map.house_name where user_house_map.user_name=name)")
public House house;
这是我尝试的
@JoinColumnOrFormula
解决方案

@Expose
@ManyToOne(targetEntity = House.class)
@JoinColumnsOrFormulas({
        @JoinColumnOrFormula(formula=@JoinFormula(value="select name from users where users.id= id", referencedColumnName="name")),
        @JoinColumnOrFormula(column = @JoinColumn(name= "house_name", referencedColumnName="house_name"))
})
public House house;
这是我的地图

@Id
@GeneratedValue
@Expose
public Long id;

@Expose
@Required
@ManyToOne
@JoinTable(
        name="user_house_map",
        joinColumns=
        @JoinColumn(unique=true,name="user_name", referencedColumnName="name"),
        inverseJoinColumns=
        @JoinColumn(name="house_name", referencedColumnName="house_name"))
private House house;
下面是数据库模式

用户

表“public.users”
列|类型|修饰符
-----------------------+-----------------------------+-----------------------------
名称|字符变化(255)|
id |整数|不为空
索引:
“用户密钥”主键,btree(id)
外键约束:
“housing_fkey”外键(名称)引用最初可延迟的user_house_map(用户名)
房屋

表“公共房屋”
列|类型|修饰符
---------------+------------------------+-----------
房屋名称|字符变化(255)|不为空
地址|文本|
城市|文本|
国家|文本|
zip |整数|
zip|u ext | integer |
电话|文字|
索引:
“house_pkey”主键,btree(house_名称)
引用人:
表“user\u house\u map”约束“house\u map\u fkey”外键(house\u name)引用house(house\u name)可延迟的初始延迟
UserHouseMap

表“public.user\u house\u map”
列|类型|修饰符
-------------+------------------------+-----------
用户名|字符变化(255)|不为空
房屋名称|字符变化(255)|不为空
索引:
“用户住宅地图”主键,btree(用户名)
“用户\房屋\地图\房屋\钥匙”B树(房屋\名称)
外键约束:
“user\u house\u map\u house\u fkey”外键(house\u name)引用最初可延迟的house(house\u name)
引用人:
表“users”约束“housing_fkey”外键(名称)引用了可延迟的用户住宅地图(用户名称)

这就是映射的外观:

@Entity
public class User {

    @Id
    private Long id;

    private String name;

    @OneToMany(mappedBy = "user")
    private List<UserHouseMap> houses = new ArrayList<>();
}

@Entity
public class House {

    @Id
    @Column(name = "house_name", nullable = false, unique = true) 
    private String house_name;

    private String address;

    @OneToMany(mappedBy = "house")
    private List<UserHouseMap> users = new ArrayList<>();
}

@Entity
public class UserHouseMap implements Serializable {

    @Id @ManyToOne
    @JoinColumn(name = "user_name", referencedColumnName = "name")
    private User user;

    @Id @ManyToOne
    @JoinColumn(name = "house_name", referencedColumnName = "house_name")
    private House house;
}
@实体
公共类用户{
@身份证
私人长id;
私有字符串名称;
@OneToMany(mappedBy=“用户”)
private List houses=new ArrayList();
}
@实体
公屋{
@身份证
@列(name=“house\u name”,nullable=false,unique=true)
私人串屋(名称);;
私有字符串地址;
@OneToMany(mappedBy=“house”)
private List users=new ArrayList();
}
@实体
公共类UserHouseMap实现了可序列化{
@Id@ManyToOne
@JoinColumn(name=“user\u name”,referencedColumnName=“name”)
私人用户;
@Id@ManyToOne
@JoinColumn(name=“house\u name”,referencedColumnName=“house\u name”)
私人住宅;
}

User
House
都可以访问与其关联的
UserHouseMap
实体,并与数据库架构相匹配。

我知道这是旧的,但我也遇到了同样的错误。您的解决方案是有效的,但是我必须做一些轻微的更改,但是我必须添加@Column(name=“name”,nullable=false)私有字符串名称;如果我不得不猜测原因,我的变量/属性名与数据库表的列名不同。仅供有相同/类似问题的其他人参考。谢谢。我添加了
nullable=false
unique=true
,这必须由任何标识符列强制执行。如果用户名和房子名是非主键,这将不起作用!!