JPA Hibernate dwa obiekty tej samej klasy - problem z mapowaniem

0

Stworzyłem prosty projekt w którym używam JPA i jako dostawce Hibernate. W klasie Robot chce mieć dwa obiekty (leftMotor i rightMotor) klasy Motor. Jak mogę to zrobić w JPA ?.

package model;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="ROBOT")
public class Robot implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(cascade=CascadeType.ALL, optional=false)
    @JoinColumn(name="ID")
    private Motor leftMotor;

    @OneToOne(cascade=CascadeType.ALL, optional=false)
    @JoinColumn(name="ID")
    private Motor rightMotor;

    public Robot() {
    }

    public Long getId() {
        return id;
    }

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

    public Motor getLeftMotor() {
        return leftMotor;
    }

    public void setLeftMotor(Motor leftMotor) {
        this.leftMotor = leftMotor;
    }

    public Motor getRightMotor() {
        return rightMotor;
    }

    public void setRightMotor(Motor rightMotor) {
        this.rightMotor = rightMotor;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Robot other = (Robot ) obj;
        if (this.id != other.id) {
            return false;
        }
        if (this.leftMotor != other.leftMotor && (this.leftMotor == null || !this.leftMotor.equals(other.leftMotor))) {
            return false;
        }
        if (this.rightMotor != other.rightMotor && (this.rightMotor == null || !this.rightMotor.equals(other.rightMotor))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = (int) (43 * hash + this.id);
        hash = 43 * hash + (this.leftMotor != null ? this.leftMotor.hashCode() : 0);
        hash = 43 * hash + (this.rightMotor != null ? this.rightMotor.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "Robot";
    }
}

package model;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 *
 * @author Piotrek
 */
@Entity
@Table(name="MOTOR")
public class Motor implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private int speed;


    public Motor() {
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public Long getId() {
        return id;
    }

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

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Motor other = (Motor) obj;
        if (this.speed != other.speed) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + this.speed;
        return hash;
    }

    @Override
    public String toString() {
        return "Motor";
    }
}
 

Błędy hibernate:

2011-01-13 08:14:28 org.hibernate.cfg.annotations.EntityBinder bindTable
INFO: Bind entity model.KheperaIII on table ROBOT
2011-01-13 08:14:28 org.hibernate.cfg.AnnotationConfiguration secondPassCompile
INFO: Hibernate Validator not found: ignoring
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: RobotMonitorPU] Unable to build EntityManagerFactory
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
        at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
        at kheperaiiimonitor.Main.persist(Main.java:31)
        at kheperaiiimonitor.Main.main(Main.java:27)
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: model.Robot column: ID (should be mapped with insert="false" update="false")
        at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:652)
        at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:674)
        at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:696)
        at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:450)
        at org.hibernate.mapping.RootClass.validate(RootClass.java:192)
        at org.hibernate.cfg.Configuration.validate(Configuration.java:1102)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1287)
        at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
        ... 5 more
Java Result: 1
0

IMO, @OneToOne to to nie będzie ;) Raczej ManyToOne/OneToMany. OneToOne odpowiada mapowianiu w którym jeden obiekt klasy A odpowiada dokładnie jednemu obiektowi klasy B, a tu masz dwa obiekty klasy Monitor przypisane do jednego obiektu klasy Robot.

1 użytkowników online, w tym zalogowanych: 0, gości: 1