【问题标题】:saveOrUpdate many-to-many table with Hibernate + MySQL使用 Hibernate + MySQL 保存或更新多对多表
【发布时间】:2014-03-03 13:59:41
【问题描述】:

我有 webapp,它使用 Hibernate 4Spring 3MySQL。 Hibernate 会话和事务由 spring 管理。

现在我对如何使用 Hibernate 将数据插入computer_app 表感到困惑。 下面是创建数据库的脚本:

CREATE TABLE computers (
computer_id INT AUTO_INCREMENT,
computer_name VARCHAR(15) NOT NULL,
ip_address VARCHAR(15) NOT NULL UNIQUE,
login VARCHAR(20) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY(computer_id)
) ENGINE=InnoDB;

CREATE TABLE applications (
app_id INT AUTO_INCREMENT,
app_name VARCHAR(255) NOT NULL,
vendor_name VARCHAR(255) NOT NULL,
license_required TINYINT(1) NOT NULL,
PRIMARY KEY(app_id)
) ENGINE=InnoDB;

CREATE TABLE computer_app (
computer_id INT,
app_id INT,
FOREIGN KEY (computer_id)
    REFERENCES computers(computer_id)
    ON DELETE CASCADE,
FOREIGN KEY (app_id)
    REFERENCES applications(app_id)
    ON DELETE CASCADE
) ENGINE = InnoDB;

这里有2个对应的类,由NetBeanscomputer_app表生成:

ComputerApp.java:

@Entity
@Table(name="computer_app" ,catalog="adminportal")
public class ComputerApp  implements Serializable {

    @EmbeddedId
    @AttributeOverrides( {
        @AttributeOverride(name="computerId", column=@Column(name="computer_id") ), 
        @AttributeOverride(name="appId", column=@Column(name="app_id") ) } )
     private ComputerAppId id;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="app_id", insertable=false, updatable=false)
     private Application applications;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="computer_id", insertable=false, updatable=false)
     private Computer computers;

    public ComputerApp() {
    }

    public ComputerApp(Application applications, Computer computers) {
        this.applications = applications;
        this.computers = computers;
    }

    public ComputerAppId getId() {
        return id;
    }

    public void setId(ComputerAppId id) {
        this.id = id;
    }

    public Application getApplications() {
        return applications;
    }

    public void setApplications(Application applications) {
        this.applications = applications;
    }

    public Computer getComputers() {
        return computers;
    }

    public void setComputers(Computer computer) {
        this.computers = computer;
    }

    @Override
    public String toString() {
        return applications.getAppName();
    }

}

ComputerAppId.java:

@Embeddable
public class ComputerAppId implements Serializable {

    @Column(name = "computer_id")
    private Integer computerId;

    @Column(name = "app_id")
    private Integer appId;

    public ComputerAppId(){

    }

    public ComputerAppId(Integer computerId, Integer appId) {
        this.computerId = computerId;
        this.appId = appId;
    }

    public Integer getComputerId() {
        return this.computerId;
    }

    public void setComputerId(Integer computerId) {
        this.computerId = computerId;
    }

    public Integer getAppId() {
        return this.appId;
    }

    public void setAppId(Integer appId) {
        this.appId = appId;
    }

    public boolean equals(Object other) {
        if ((this == other)) {
            return true;
        }
        if ((other == null)) {
            return false;
        }
        if (!(other instanceof ComputerAppId)) {
            return false;
        }
        ComputerAppId castOther = (ComputerAppId) other;

        return ((this.getComputerId() == castOther.getComputerId()) || (this.getComputerId() != null && castOther.getComputerId() != null && this.getComputerId().equals(castOther.getComputerId())))
                && ((this.getAppId() == castOther.getAppId()) || (this.getAppId() != null && castOther.getAppId() != null && this.getAppId().equals(castOther.getAppId())));
    }

    public int hashCode() {
        int result = 17;

        result = 37 * result + (getComputerId() == null ? 0 : this.getComputerId().hashCode());
        result = 37 * result + (getAppId() == null ? 0 : this.getAppId().hashCode());
        return result;
    }

}

如何使用 Hibernate 在 computer_app 数据表中的 saveOrUpdate() 数据?必须创建 2 个生成类的哪个实例 - 一个或两个?

请指出解决方案或提供一些代码..我真的需要做到这一点,直到明天!每个答案都受到高度赞赏并立即回复!如果您需要一些额外的代码 - 请告诉我。

谢谢。

【问题讨论】:

    标签: java mysql sql spring hibernate


    【解决方案1】:

    如下定义ComputerApplication 表之间的@manytomany 关系 hibernate 将负责将记录插入到您的computer_app 表中,无需为computer_app 表定义单独的表,如下所示

    电脑

    @Entity
    @Table(name="computers")
    public class Computer {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name = "computer_id")
    private int id;
    
    @ManyToMany(cascade = {CascadeType.ALL},fetch=FetchType.EAGER)
    @JoinTable(name="computer_app", 
            joinColumns={@JoinColumn(name="computer_id")}, 
            inverseJoinColumns={@JoinColumn(name="app_id")})
    private Set<Application> applications = new HashSet<Application>();
    
    //Setter && Getters methods
    
    }
    

    应用程序

    @Entity
    @Table(name="applications")
    public class Application {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name = "app_id")
    private int id;
    
    @ManyToMany(mappedBy="applications",fetch=FetchType.EAGER)
    private Set<Computer> computers = new HashSet<Computer>();
    
    //Setter && Getters methods
    
    }
    

    保存实体

    SessionFactory sf = HibernateUtil.getSessionFactory();
    Session session = sf.openSession();
    session.beginTransaction();
    
    Application app1 = new Application();
    Application app2 = new Application();
    Computer comp = new Computer();
    comp.getApplications().add(app1);
    comp.getApplications().add(app2);
    session.saveOrUpdate(comp);
    
    session.getTransaction().commit();
    session.close();
    

    这将自动将记录插入所有三个表中

    更多参考阅读这篇文章

    Hibernate Many To Many Annotation Mapping Tutorial

    希望这能解决您的问题...!

    【讨论】:

      【解决方案2】:

      您只需要创建一台新计算机:

      Computer c = new Computer(computer_name,ip_address,ip_address ,login, password );
      

      和一个应用程序:

      Application a = new Application(app_name,vendor_name,license_required );
      

      然后你会这样做:

      ComputerApp ca = new ComputerApp(a,c);
      

      然后你可以像 Janus 提到的那样坚持它。 Hibernate 将处理外键,因为您将在构造函数中将计算机 c 和应用程序 a 作为参数传递

      【讨论】:

        【解决方案3】:

        您可以使用 EntityManager 保存对象:

        public void save(ComputerApp t){
        // begin transaction 
        em.getTransaction().begin();
        if (!em.contains(t)) {
            // persist object - add to entity manager
            em.persist(t);
            // flush em - save to DB
            em.flush();
        }
        // commit transaction at all
        em.getTransaction().commit();
        

        }

        【讨论】:

        • 但是 ComputerAppId 呢?我也必须提供吗?或者它会以某种方式从 ComputerApp 生成?
        • 在我看来,如果在运行时未设置,它将在数据库表中保持为空。您可以使用@GeneratedValue(strategy=GenerationType.IDENTITY) 生成一个自动递增的 id,但它不适用于对象。
        • ComputerApp类中是否缺少持久化注解?
        猜你喜欢
        • 1970-01-01
        • 2018-07-22
        • 2019-02-11
        • 2013-06-17
        • 2014-09-02
        • 2013-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多