我正在尝试使用带注释的Hibernate创建以下结构:
为了创建ManyToMany关系,我创建了两个名为SessionRiu和SessionRiuId(pk)的类。这样Session类有两个外键(agend_id和user_id)但是当我尝试从操作创建OneToMany时,hibernate不会使用session中的id创建外来键:
Session FKs:
由于我是java和hibernate的初学者,我很感激有关我的代码的任何建议。
我的目标是正确创建这四个表的关系,最后使用带有Operation.session_id参考Session.id列的jpa创建Operation类的fk。
正是这样: ALTER TABLE操作ADD FOREIGN KEY(session_id)REFERENCES Sessions(id)
我的档案:
基类:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.riuapp.model;
import java.util.Calendar;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
*
* @author vdasilva
*/
@MappedSuperclass
public abstract class Base {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
Long id;
@Column(name="status")
private StatusEnum status;
@Column(name = "dt_create", columnDefinition="DATETIME")
@Temporal(TemporalType.TIMESTAMP)
private Date dt_create;
@Column(name = "dt_update", columnDefinition="DATETIME")
@Temporal(TemporalType.TIMESTAMP)
private Date dt_update;
public Base(){
this.dt_create = new Date();
}
///*************************************************************************
///GETTERS AND SETTERS
///*************************************************************************
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Enumerated(EnumType.ORDINAL)
public StatusEnum getStatus() {
return this.status;
}
public void setStatus(StatusEnum status) {
this.status = status;
}
/**
* @return the dt_create
*/
public Date getDt_create() {
return dt_create;
}
/**
* @param dt_create the dt_create to set
*/
public void setDt_create(Date dt_create) {
this.dt_create = dt_create;
}
/**
* @return the dt_update
*/
public Date getDt_update() {
return dt_update;
}
/**
* @param dt_update the dt_update to set
*/
public void setDt_update(Date dt_update) {
this.dt_update = dt_update;
}
}
代理类:
package com.riuapp.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="Agents", catalog = "TestMvn")
public class Agent extends Base implements java.io.Serializable {
/*@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@SuppressWarnings("FieldMayBeFinal")
private List<SessionRiu> sessions;*/
HashSet<SessionRiu> sessions = new HashSet<SessionRiu>(0);
@Column(name="name")
String name;
@Column(name="login")
String login;
@Column(name="pass")
String pass;
@Column(name="description")
String description;
@Column(name="client_id")
Long client_id;
public Agent(Long id, String name, String description) {
//this.sessions = new ArrayList<SessionRiu>();
this.id = id;
this.name = name;
this.description = description;
}
public Agent() {
//this.sessions = new ArrayList<SessionRiu>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getClientId() {
return client_id;
}
public void setClientId(Long x) {
this.client_id = x;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.agent", cascade=CascadeType.ALL)
public Set<SessionRiu> getSessions() {
return this.sessions;
}
public void setSessions(HashSet<SessionRiu> sessions) {
this.sessions = sessions;
}
}
用户类:
package com.riuapp.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="Users", catalog = "TestMvn")
public class User extends Base implements java.io.Serializable {
private String name;
private String description;
private Long client_id;
private HashSet<SessionRiu> sessions = new HashSet<SessionRiu>(0);
public User(Long id, String name, String description) {
// this.sessions = new ArrayList<SessionRiu>();
this.id = id;
this.name = name;
this.description = description;
}
public User() {
//this.sessions = new ArrayList<SessionRiu>();
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Column(name="client_id")
public Long getClientId() {
return client_id;
}
public void setClientId(Long x) {
this.client_id = x;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.user", cascade=CascadeType.ALL)
public Set<SessionRiu> getSessions() {
return this.sessions;
}
public void setSessions(HashSet<SessionRiu> sessions) {
this.sessions = sessions;
}
}
SessionRiuId课程:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.riuapp.model;
import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;
@Embeddable
public class SessionRiuId implements java.io.Serializable {
private Agent agent;
private User user;
@ManyToOne
public Agent getAgent() {
return agent;
}
public void setAgent(Agent agent) {
this.agent = agent;
}
@ManyToOne
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SessionRiuId that = (SessionRiuId) o;
if (agent != null ? !agent.equals(that.agent) : that.agent != null) return false;
if (user != null ? !user.equals(that.user) : that.user != null)
return false;
return true;
}
public int hashCode() {
int result;
result = (agent != null ? agent.hashCode() : 0);
result = 31 * result + (user != null ? user.hashCode() : 0);
return result;
}
}
会话班级:
package com.riuapp.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table(name = "Sessions", catalog = "TestMvn")
@AssociationOverrides({
@AssociationOverride(name = "pk.agent",
joinColumns = @JoinColumn(name = "agent_id")),
@AssociationOverride(name = "pk.user",
joinColumns = @JoinColumn(name = "user_id")) })
public class SessionRiu extends Base implements java.io.Serializable{
private SessionRiuId pk = new SessionRiuId();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "sessionriu", cascade=CascadeType.ALL, orphanRemoval = true)
private HashSet<Operation> operations = new HashSet<Operation>(0);
@EmbeddedId
public SessionRiuId getPk() {
return pk;
}
public void setPk(SessionRiuId pk) {
this.pk = pk;
}
@Transient
public Agent getAgent() {
return getPk().getAgent();
}
public void setAgent(Agent agent) {
this.getPk().setAgent(agent);
}
@Transient
public User getUser() {
return this.getPk().getUser();
}
public void setUser(User user) {
this.getPk().setUser(user);
}
private StateEnum state;
@Column(name="duration")
private double duration;
@Column(name="ip")
private String ip;
@Column(name="browser")
private String browser;
public SessionRiu(Agent a, User u) {
this.state = StateEnum.STATE0;
this.getPk().setAgent(a);
this.getPk().setUser(u);
}
public SessionRiu(StateEnum x, Agent a, User u) {
this.state = x;
this.getPk().setAgent(a);
this.getPk().setUser(u);
}
/**
* @return the state
*/
public StateEnum getState() {
return state;
}
/**
* @param state the state to set
*/
public void setState(StateEnum state) {
this.state = state;
}
/**
* @return the duration
*/
public double getDuration() {
return duration;
}
/**
* @param duration the duration to set
*/
public void setDuration(double duration) {
this.duration = duration;
}
/**
* @return the ip
*/
public String getIp() {
return ip;
}
/**
* @param ip the ip to set
*/
public void setIp(String ip) {
this.ip = ip;
}
/**
* @return the browser
*/
public String getBrowser() {
return browser;
}
/**
* @param browser the browser to set
*/
public void setBrowser(String browser) {
this.browser = browser;
}
public HashSet<Operation> getOperations() {
return this.operations;
}
public void setOperations(HashSet<Operation> operations) {
this.operations = operations;
}
}
最后是操作类:
package com.riuapp.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "Operation", catalog = "TestMvn")
public class Operation extends Base implements java.io.Serializable{
@ManyToOne
@JoinColumn(referencedColumnName = "id")
private SessionRiu sessionRiu;
private StateEnum state;
private ResultEnum result;
@Column(name="duration")
private double duration;
@Column(name="ip")
private String ip;
@Column(name="browser")
private String browser;
public Operation(SessionRiu sessionRiu) {
this.state = StateEnum.STATE0;
this.result = ResultEnum.PENDING;
this.sessionRiu = sessionRiu;
}
public Operation(SessionRiu sessionRiu, StateEnum state, ResultEnum result) {
this.state = state;
this.result = result;
this.sessionRiu = sessionRiu;
}
/**
* @return the state
*/
public StateEnum getState() {
return state;
}
/**
* @param state the state to set
*/
public void setState(StateEnum state) {
this.state = state;
}
/**
* @return the duration
*/
public double getDuration() {
return duration;
}
/**
* @param duration the duration to set
*/
public void setDuration(double duration) {
this.duration = duration;
}
/**
* @return the ip
*/
public String getIp() {
return ip;
}
/**
* @param ip the ip to set
*/
public void setIp(String ip) {
this.ip = ip;
}
/**
* @return the browser
*/
public String getBrowser() {
return browser;
}
/**
* @param browser the browser to set
*/
public void setBrowser(String browser) {
this.browser = browser;
}
public SessionRiu getSessionRiu()
{
return this.sessionRiu;
}
public void setSessionRiu(SessionRiu sessionRiu)
{
this.sessionRiu = sessionRiu;
}
}
观察:
如果删除连接线,则创建两个fks(agent_id和user_id)作为会话表=(
@Entity
@Table(name = "Operation", catalog = "TestMvn")
public class Operation extends Base implements java.io.Serializable{
@ManyToOne
//@JoinColumn(referencedColumnName = "id")
private SessionRiu sessionRiu;
答案 0 :(得分:1)
JPA不允许嵌入式ID中的关系,并且由于您的Session表具有ID字段,因此我不太确定您尝试将代理和用户引用放在嵌入式ID中时所追求的是什么。与表结构匹配的最简单模型将采用以下形式:
@Table(name="Agents", catalog = "TestMvn")
public class Agent {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
Long id;
@OneToMany(mappedby='agent', cascade = CascadeType.ALL, orphanRemoval = true)
private List<SessionRiu> sessions;
}
@Entity
@Table(name = "Sessions", catalog = "TestMvn")
public class SessionRiu implements java.io.Serializable{
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
Long id;
@ManyToOne
@JoinColumn(name = "agent_id")
private Agent agent;
}
添加用户和操作将遵循相同的模式。
如果你想在会话中使用复合PK而不是使用session的id字段,JPA 2.1允许这样的内容:
@Entity
@Table(name = "Sessions", catalog = "TestMvn")
@IdClass(SessionRiuPK.class)
public class SessionRiu implements java.io.Serializable{
@Id
@ManyToOne
@JoinColumn(name = "agent_id")
private Agent agent;
@Id
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
...
}
用
public class SessionRiuPK {
Long user;
Long agent;
}
答案 1 :(得分:1)
从底线开始,id
表中已有Session
,因此不需要复合ID。映射看起来像这样:
@Entity
@Table(name = "Sessions", catalog = "TestMvn")
public class SessionRiu extends Base implements java.io.Serializable {
@Id
private Long id;
@ManyToOne
private User user;
@ManyToOne
private Agent agent;
//other mappings here
}
这样,您甚至不需要@EmbeddableId
课程。
现在,mappedBy
和@OneToMany
需要Agent
User
:
@Entity
@Table(name="Users", catalog = "TestMvn")
public class User extends Base implements java.io.Serializable {
@Id
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy="user")
private List<SessionRiu> sessions = new ArrayList<>();
//other mappings here
}
@Entity
@Table(name="Agents", catalog = "TestMvn")
public class Agent extends Base implements java.io.Serializable {
@Id
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy="agent")
private List<SessionRiu> sessions = new ArrayList<>();
//other mappings here
}
Operation
中的相同内容:
@Entity
@Table(name = "Operation", catalog = "TestMvn")
public class Operation extends Base implements java.io.Serializable{
@Id
private Long id;
@ManyToOne
private SessionRiu sessionRiu;
//other mappings here
}