Java 如何使用JPA和Hibernate连接非主键上的表
我有3种型号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作为一种
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
,这必须由任何标识符列强制执行。如果用户名和房子名是非主键,这将不起作用!!