问题描述
我想请帮助我找出更新其他表中外键值的解决方案。 例如:-
如果我们获取了设备表
列是:-设备名 设备编号 显示名称 用户身份 roomId isDeleted
其他表是“房间表”
列是:-roomName roomId 房型 isDeleted
听到它看起来像一对多的关系。 即一间房间将容纳许多设备。
在以上两个表中,roomId是Rooms表中的主键,而roomId是Device表中的原键。 因此,听到我们想要的是我们必须更新DeviceTable中的roomId。 我尝试过,但是,我无法找到解决方案,我要求你们帮我解决这个问题。
数据库表将像
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
希望你们能理解上表。
所以,现在我要做的任务是:- 我要更新设备表中的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$1.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$1.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();