使用两个外键关系时的 Hibernate 查询异常
Hibernate query exception when using two foreign key relations
我正在开发 Spring-MVC 应用程序。在应用程序中,我正在研究聊天功能。您可以将聊天功能想象成类似于 facebook 风格。在这里,有两个用户之间的对话,当加载对话时,可以看到里面的文本。所以我有 3 个表,用户、对话、回复。因此 Conversation 与用户只有两个外键关系,即发送者和接收者。
每当有新消息到达时,都会将其添加到回复中,并与对话建立外键关系。这样,每当我需要加载对话时,我只需搜索两个用户 ID,然后从回复中加载它。
现在,当我尝试在数据库中搜索 conversationid 时,我正在使用查询来搜索它们,但出现错误。错误代码如下:
错误代码:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.QueryException: could not resolve property: userinfo_id of: com.WirTauschen.model.User [from com.WirTauschen.model.Messages as m where m.sender.id=:senderid and m.receiver.userinfo_id=:receiverid]
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:152)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
用户模型:
@Entity
@Table(name="userinfo")
public class User implements UserDetails{
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "user_seq_gen")
@SequenceGenerator(name ="user_seq_gen", sequenceName = "user_seq")
public int id;
@OneToMany(mappedBy = "sender", fetch = FetchType.EAGER)
private Set<Messages> messages1 = new HashSet<Messages>();
@OneToMany(mappedBy = "receiver", fetch = FetchType.EAGER)
private Set<Messages> messages2 = new HashSet<Messages>();
// getters 和 setters 省略
}
消息模型:
@Entity
@Table(name = "conversation")
public class Messages {
@ManyToOne
@JoinColumn(name = "id")
private User sender;
@ManyToOne
@JoinColumn(name = "userinfo_id")
private User receiver;
// Getters and setters ommitted
}
消息DAOImpl :
@Override
public Long returnConversationId(int senderid, int receiverid) {
session = this.sessionFactory.getCurrentSession();
Query query1 = session.createQuery("from Messages as m where m.sender.id=:senderid and m.receiver.userinfo_id=:receiverid");
query1.setParameter("senderid",senderid);
query1.setParameter("receiverid",receiverid);
List<Messages> firstDataList = query1.list();
List<Messages> secondDataList = new ArrayList<Messages>();
if(firstDataList.isEmpty()) {
Query query2 = session.createQuery("from Messages as m where m.sender.id=:receiverid and m.receiver.userinfo_id=:senderid");
query2.setParameter("senderid", senderid);
query2.setParameter("receiverid", receiverid);
secondDataList = query2.list();
} else {
for(Messages messages : firstDataList){
return messages.getConversation_id();
}
}
if(secondDataList.isEmpty()){
return null;
} else {
for (Messages messages : secondDataList){
return messages.getConversation_id();
}
}
return null;
}
SQL 代码:
CREATE TABLE userinfo
(
id integer NOT NULL,
email character varying,
username character varying,
password character varying,
accountstatus boolean DEFAULT false,
CONSTRAINT id PRIMARY KEY (id)
)
CREATE TABLE conversation
(
conversation_id numeric NOT NULL,
id integer NOT NULL,
userinfo_id integer NOT NULL,
lastmessage character varying,
CONSTRAINT conversation_id PRIMARY KEY (conversation_id),
CONSTRAINT userinfo_conversation_fk FOREIGN KEY (id)
REFERENCES userinfo (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT userinfo_conversation_fk1 FOREIGN KEY (userinfo_id)
REFERENCES userinfo (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
欢迎任何指点。请注意,数据库中有一列 userinfo_id。谢谢你。
你的模型 "userinfo_id" 在哪里 "User",你应该有这样的东西:
@Id
@Column(name="id")
@GeneratedValue
private int id;
在您的消息模型中:
@Entity
@Table(name = "conversation")
public class Messages {
@ManyToOne
@JoinColumn(name = "id")
private User sender;
@ManyToOne
@JoinColumn(name = "id")
private User receiver;
// Getters and setters ommitted
}
我正在开发 Spring-MVC 应用程序。在应用程序中,我正在研究聊天功能。您可以将聊天功能想象成类似于 facebook 风格。在这里,有两个用户之间的对话,当加载对话时,可以看到里面的文本。所以我有 3 个表,用户、对话、回复。因此 Conversation 与用户只有两个外键关系,即发送者和接收者。
每当有新消息到达时,都会将其添加到回复中,并与对话建立外键关系。这样,每当我需要加载对话时,我只需搜索两个用户 ID,然后从回复中加载它。
现在,当我尝试在数据库中搜索 conversationid 时,我正在使用查询来搜索它们,但出现错误。错误代码如下:
错误代码:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.QueryException: could not resolve property: userinfo_id of: com.WirTauschen.model.User [from com.WirTauschen.model.Messages as m where m.sender.id=:senderid and m.receiver.userinfo_id=:receiverid]
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:152)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
用户模型:
@Entity
@Table(name="userinfo")
public class User implements UserDetails{
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "user_seq_gen")
@SequenceGenerator(name ="user_seq_gen", sequenceName = "user_seq")
public int id;
@OneToMany(mappedBy = "sender", fetch = FetchType.EAGER)
private Set<Messages> messages1 = new HashSet<Messages>();
@OneToMany(mappedBy = "receiver", fetch = FetchType.EAGER)
private Set<Messages> messages2 = new HashSet<Messages>();
// getters 和 setters 省略 }
消息模型:
@Entity
@Table(name = "conversation")
public class Messages {
@ManyToOne
@JoinColumn(name = "id")
private User sender;
@ManyToOne
@JoinColumn(name = "userinfo_id")
private User receiver;
// Getters and setters ommitted
}
消息DAOImpl :
@Override
public Long returnConversationId(int senderid, int receiverid) {
session = this.sessionFactory.getCurrentSession();
Query query1 = session.createQuery("from Messages as m where m.sender.id=:senderid and m.receiver.userinfo_id=:receiverid");
query1.setParameter("senderid",senderid);
query1.setParameter("receiverid",receiverid);
List<Messages> firstDataList = query1.list();
List<Messages> secondDataList = new ArrayList<Messages>();
if(firstDataList.isEmpty()) {
Query query2 = session.createQuery("from Messages as m where m.sender.id=:receiverid and m.receiver.userinfo_id=:senderid");
query2.setParameter("senderid", senderid);
query2.setParameter("receiverid", receiverid);
secondDataList = query2.list();
} else {
for(Messages messages : firstDataList){
return messages.getConversation_id();
}
}
if(secondDataList.isEmpty()){
return null;
} else {
for (Messages messages : secondDataList){
return messages.getConversation_id();
}
}
return null;
}
SQL 代码:
CREATE TABLE userinfo
(
id integer NOT NULL,
email character varying,
username character varying,
password character varying,
accountstatus boolean DEFAULT false,
CONSTRAINT id PRIMARY KEY (id)
)
CREATE TABLE conversation
(
conversation_id numeric NOT NULL,
id integer NOT NULL,
userinfo_id integer NOT NULL,
lastmessage character varying,
CONSTRAINT conversation_id PRIMARY KEY (conversation_id),
CONSTRAINT userinfo_conversation_fk FOREIGN KEY (id)
REFERENCES userinfo (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT userinfo_conversation_fk1 FOREIGN KEY (userinfo_id)
REFERENCES userinfo (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
欢迎任何指点。请注意,数据库中有一列 userinfo_id。谢谢你。
你的模型 "userinfo_id" 在哪里 "User",你应该有这样的东西:
@Id
@Column(name="id")
@GeneratedValue
private int id;
在您的消息模型中:
@Entity
@Table(name = "conversation")
public class Messages {
@ManyToOne
@JoinColumn(name = "id")
private User sender;
@ManyToOne
@JoinColumn(name = "id")
private User receiver;
// Getters and setters ommitted
}