如何使用 CriteriaUpdate 编写连接?
How to write Joins using CriteriaUpdate?
我想请求帮助我找到更新其他 table 中的外键值的解决方案。
例如:-
如果我们使用设备 Table
列是:- 设备名称
设备编号
显示名称
用户身份
房间号
已删除
其他 table 是房间 Table
列是:- roomName
房间号
房型
已删除
听说它看起来像一对多的关系。
即,一个房间将包含许多设备。
在上面两个tables roomId 是Rooms Table 中的主键,roomId 是Device Table 中的forgin key。
所以,听到我们想要的是我们必须更新 DeviceTable 中的 roomId。
我试过了,但是我找不到解决方案,我请求你们帮我解决这个问题。
数据库 tables 会像
Room Table(room_table)
room_id room_name room_type
1 ROOM1 ROOM_TYPE1
2 ROOM2 ROOM_TYPE2
Device Table like(device_table)
device_id device_name display_name room_id
1 DEVICE1 DISPLAY1 1
2 DEVICE2 DISPLAY2 2
以上table希望大家理解
所以,现在我需要完成的任务是:-
我想更新设备 table 中的 roomId,即对于 DEVICE2,我们必须将 roomId 1 更新为 roomId 2,如下所示。
Device Table like(device_table)
device_id device_name display_name room_id
1 DEVICE1 DISPLAY1 1
2 DEVICE2 DISPLAY2 2
为此,我编写了 java 代码,例如:-
@Entity
@Table(name = "device_table")
public class Device {
@Id
@Column(name = "device_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int deviceId;
@Column(name = "device_name")
private String deviceName;
@Column(name = "display_name")
private String dispalyName;
@ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
//private List<Room> roomList = new ArrayList<>();
@JoinColumn(name = "ROOM_ID")
private Room roomList;
//setters & getters
}
@Entity
@Table(name = "room_table")
public class Room {
@Id
@Column(name = "room_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int roomId;
@Column(name = "room_name")
private String roomName;
@Column(name = "room_type")
private String roomType;
@OneToMany(mappedBy="roomList")
private Collection<Device> deviceList = new ArrayList<>();
//setters & getters
}
为了更新,我尝试了如下代码。
public class SaveDataClientTest {
public static void main(String[] args) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
session.beginTransaction();
CriteriaBuilder userBuilder = session.getCriteriaBuilder();
CriteriaUpdate<Device> deviceUpdate = userBuilder.createCriteriaUpdate(Device.class);
Root<Device> deviceUpdateRoot = deviceUpdate.from(Device.class);
Subquery<Device> deviceSubquery = deviceUpdate.subquery(Device.class);
Root<Device> roomRoot = deviceSubquery.from(Device.class);
Join<Device, Room> join = roomRoot.join("roomList", JoinType.LEFT);
deviceUpdate.set(deviceUpdateRoot.get("dispalyName"), "DISPLAY12345");
deviceUpdate.set(join.get("roomId"), 2);
deviceUpdate.where(userBuilder.equal(deviceUpdateRoot.get("deviceName"), "DEVICE2"));
int returnValue = session.createQuery(deviceUpdate).executeUpdate();
System.out.println(returnValue);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
我收到类似
的错误
Oct 01, 2020 8:00:03 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
Oct 01, 2020 8:00:03 PM org.hibernate.hql.internal.ast.ErrorCounter reportError
ERROR: Invalid path: 'generatedAlias1.roomId'
Oct 01, 2020 8:00:03 PM org.hibernate.hql.internal.ast.ErrorCounter reportError
ERROR: Invalid path: 'generatedAlias1.roomId'
Invalid path: 'generatedAlias1.roomId'
at org.hibernate.hql.internal.ast.util.LiteralProcessor.lookupConstant(LiteralProcessor.java:111)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:214)
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:1038)
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:1026)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.assignment(HqlSqlBaseWalker.java:1054)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.setClause(HqlSqlBaseWalker.java:765)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.updateStatement(HqlSqlBaseWalker.java:381)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:269)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:266)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3324)
at org.hibernate.query.criteria.internal.AbstractManipulationCriteriaQuery.buildCompiledQuery(AbstractManipulationCriteriaQuery.java:112)
at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:127)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3628)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:203)
at com.infotech.client.SaveDataClientTest.main(SaveDataClientTest.java:54)
Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.roomId' [update com.infotech.entities.Device as generatedAlias0 set generatedAlias0.dispalyName = :param0, generatedAlias1.roomId = 2 where generatedAlias0.deviceName=:param1]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:133)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:164)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:670)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3324)
at org.hibernate.query.criteria.internal.AbstractManipulationCriteriaQuery.buildCompiledQuery(AbstractManipulationCriteriaQuery.java:112)
at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:127)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3628)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:203)
at com.infotech.client.SaveDataClientTest.main(SaveDataClientTest.java:54)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.roomId' [update com.infotech.entities.Device as generatedAlias0 set generatedAlias0.dispalyName = :param0, generatedAlias1.roomId = 2 where generatedAlias0.deviceName=:param1]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:272)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662)
... 6 more
你能帮我解决这个问题吗?
谢谢。
您尝试过以下方法吗?
CriteriaUpdate<Device> deviceUpdate = userBuilder.createCriteriaUpdate(Device.class);
Root<Device> deviceUpdateRoot = deviceUpdate.from(Device.class);
deviceUpdate.set(deviceUpdateRoot.get("dispalyName"), "DISPLAY12345");
deviceUpdate.set(deviceUpdateRoot.get("roomList").get("roomId"), 2);
deviceUpdate.where(userBuilder.equal(deviceUpdateRoot.get("deviceName"), "DEVICE2"));
int returnValue = session.createQuery(deviceUpdate).executeUpdate();
还是这个?
CriteriaUpdate<Device> deviceUpdate = userBuilder.createCriteriaUpdate(Device.class);
Root<Device> deviceUpdateRoot = deviceUpdate.from(Device.class);
deviceUpdate.set(deviceUpdateRoot.get("dispalyName"), "DISPLAY12345");
deviceUpdate.set(deviceUpdateRoot.get("roomList"), session.getReference(Room.class, 2));
deviceUpdate.where(userBuilder.equal(deviceUpdateRoot.get("deviceName"), "DEVICE2"));
int returnValue = session.createQuery(deviceUpdate).executeUpdate();
我想请求帮助我找到更新其他 table 中的外键值的解决方案。 例如:-
如果我们使用设备 Table
列是:- 设备名称 设备编号 显示名称 用户身份 房间号 已删除
其他 table 是房间 Table
列是:- roomName 房间号 房型 已删除
听说它看起来像一对多的关系。 即,一个房间将包含许多设备。
在上面两个tables roomId 是Rooms Table 中的主键,roomId 是Device Table 中的forgin key。 所以,听到我们想要的是我们必须更新 DeviceTable 中的 roomId。 我试过了,但是我找不到解决方案,我请求你们帮我解决这个问题。
数据库 tables 会像
Room Table(room_table)
room_id room_name room_type
1 ROOM1 ROOM_TYPE1
2 ROOM2 ROOM_TYPE2
Device Table like(device_table)
device_id device_name display_name room_id
1 DEVICE1 DISPLAY1 1
2 DEVICE2 DISPLAY2 2
以上table希望大家理解
所以,现在我需要完成的任务是:- 我想更新设备 table 中的 roomId,即对于 DEVICE2,我们必须将 roomId 1 更新为 roomId 2,如下所示。
Device Table like(device_table)
device_id device_name display_name room_id
1 DEVICE1 DISPLAY1 1
2 DEVICE2 DISPLAY2 2
为此,我编写了 java 代码,例如:-
@Entity
@Table(name = "device_table")
public class Device {
@Id
@Column(name = "device_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int deviceId;
@Column(name = "device_name")
private String deviceName;
@Column(name = "display_name")
private String dispalyName;
@ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
//private List<Room> roomList = new ArrayList<>();
@JoinColumn(name = "ROOM_ID")
private Room roomList;
//setters & getters
}
@Entity
@Table(name = "room_table")
public class Room {
@Id
@Column(name = "room_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int roomId;
@Column(name = "room_name")
private String roomName;
@Column(name = "room_type")
private String roomType;
@OneToMany(mappedBy="roomList")
private Collection<Device> deviceList = new ArrayList<>();
//setters & getters
}
为了更新,我尝试了如下代码。
public class SaveDataClientTest {
public static void main(String[] args) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
session.beginTransaction();
CriteriaBuilder userBuilder = session.getCriteriaBuilder();
CriteriaUpdate<Device> deviceUpdate = userBuilder.createCriteriaUpdate(Device.class);
Root<Device> deviceUpdateRoot = deviceUpdate.from(Device.class);
Subquery<Device> deviceSubquery = deviceUpdate.subquery(Device.class);
Root<Device> roomRoot = deviceSubquery.from(Device.class);
Join<Device, Room> join = roomRoot.join("roomList", JoinType.LEFT);
deviceUpdate.set(deviceUpdateRoot.get("dispalyName"), "DISPLAY12345");
deviceUpdate.set(join.get("roomId"), 2);
deviceUpdate.where(userBuilder.equal(deviceUpdateRoot.get("deviceName"), "DEVICE2"));
int returnValue = session.createQuery(deviceUpdate).executeUpdate();
System.out.println(returnValue);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
我收到类似
的错误Oct 01, 2020 8:00:03 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
Oct 01, 2020 8:00:03 PM org.hibernate.hql.internal.ast.ErrorCounter reportError
ERROR: Invalid path: 'generatedAlias1.roomId'
Oct 01, 2020 8:00:03 PM org.hibernate.hql.internal.ast.ErrorCounter reportError
ERROR: Invalid path: 'generatedAlias1.roomId'
Invalid path: 'generatedAlias1.roomId'
at org.hibernate.hql.internal.ast.util.LiteralProcessor.lookupConstant(LiteralProcessor.java:111)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:214)
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:1038)
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:1026)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.assignment(HqlSqlBaseWalker.java:1054)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.setClause(HqlSqlBaseWalker.java:765)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.updateStatement(HqlSqlBaseWalker.java:381)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:269)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:266)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3324)
at org.hibernate.query.criteria.internal.AbstractManipulationCriteriaQuery.buildCompiledQuery(AbstractManipulationCriteriaQuery.java:112)
at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:127)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3628)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:203)
at com.infotech.client.SaveDataClientTest.main(SaveDataClientTest.java:54)
Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.roomId' [update com.infotech.entities.Device as generatedAlias0 set generatedAlias0.dispalyName = :param0, generatedAlias1.roomId = 2 where generatedAlias0.deviceName=:param1]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:133)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:164)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:670)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3324)
at org.hibernate.query.criteria.internal.AbstractManipulationCriteriaQuery.buildCompiledQuery(AbstractManipulationCriteriaQuery.java:112)
at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:127)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:3628)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:203)
at com.infotech.client.SaveDataClientTest.main(SaveDataClientTest.java:54)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.roomId' [update com.infotech.entities.Device as generatedAlias0 set generatedAlias0.dispalyName = :param0, generatedAlias1.roomId = 2 where generatedAlias0.deviceName=:param1]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:272)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662)
... 6 more
你能帮我解决这个问题吗? 谢谢。
您尝试过以下方法吗?
CriteriaUpdate<Device> deviceUpdate = userBuilder.createCriteriaUpdate(Device.class);
Root<Device> deviceUpdateRoot = deviceUpdate.from(Device.class);
deviceUpdate.set(deviceUpdateRoot.get("dispalyName"), "DISPLAY12345");
deviceUpdate.set(deviceUpdateRoot.get("roomList").get("roomId"), 2);
deviceUpdate.where(userBuilder.equal(deviceUpdateRoot.get("deviceName"), "DEVICE2"));
int returnValue = session.createQuery(deviceUpdate).executeUpdate();
还是这个?
CriteriaUpdate<Device> deviceUpdate = userBuilder.createCriteriaUpdate(Device.class);
Root<Device> deviceUpdateRoot = deviceUpdate.from(Device.class);
deviceUpdate.set(deviceUpdateRoot.get("dispalyName"), "DISPLAY12345");
deviceUpdate.set(deviceUpdateRoot.get("roomList"), session.getReference(Room.class, 2));
deviceUpdate.where(userBuilder.equal(deviceUpdateRoot.get("deviceName"), "DEVICE2"));
int returnValue = session.createQuery(deviceUpdate).executeUpdate();