2016-07-05 36 views
1

我試圖創建一個使用與註釋的Hibernate後續結構:多對一註釋到特定的列

Schema

要創建我創造了兩個類叫做SessionRiu和SessionRiuId(PK)一個多對多的關係。這樣,會話類有兩個外鍵(agend_id和user_ID的),但是當我嘗試從操作的一對多休眠不使用id從會話創建外:

會議FKS:

enter image description here

操作FKS(): enter image description here

由於我初學Java和冬眠,我將不勝感激的任何建議我的代碼。

我的目標是正確創建這四個表的關係,並最終使用jpa的Operation.session_id引用Session.id創建Operation類的fk。

確切說: ALTER TABLE操作添加外鍵(SESSION_ID)參考文獻會話(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; 
    } 

} 

Session類:

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; 
    } 

} 

最後的c動作姑娘

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; 

enter image description here

+0

你爲什麼要使用複合PK的sessionRui實體,而不是僅僅的會話ID?對於看起來像具有M:1反向引用的簡單1:M映射,這看起來非常複雜。您將需要使用1:M上的'mappedby'標識來告訴您外鍵已被控制並映射到其他M:1映射中。 – Chris

回答

1

底線是,你已經有一個idSession表,所以不需要複合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@OneToManyAgentUser

@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 
} 
+1

感謝弗拉德,這真的很清楚。其實我從另一篇文章中得到了嵌入代碼,這是我的巨大錯誤。 – Vitorlui

1

JPA不允許嵌入ID中的關係,並且由於您的Session表具有ID字段,因此我不太確定您試圖將Ag ent和用戶引用的嵌入式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; 
} 

在用戶和操作中添加將遵循相同的模式。

如果你想在會議上,而不是使用會話的ID字段的複合PK,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; 
}