ManyToOne注释到特定列

时间:2016-07-05 13:04:05

标签: java mysql hibernate jpa annotations

我正在尝试使用带注释的Hibernate创建以下结构:

Schema

为了创建ManyToMany关系,我创建了两个名为SessionRiu和SessionRiuId(pk)的类。这样Session类有两个外键(agend_id和user_id)但是当我尝试从操作创建OneToMany时,hibernate不会使用session中的id创建外来键:

Session FKs:

enter image description here

操作FK(): enter image description here

由于我是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;

enter image description here

2 个答案:

答案 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
}