Spring Inheritance, многие ко многим, повторяющийся столбец в отображении для объекта - PullRequest
0 голосов
/ 20 мая 2018

Диаграмма классов

Привет, я пытаюсь отобразить связь многих со многими между двумя классами Employee и Manager, выходящими из класса Person.Проблема в том, что оба класса имеют одинаковые идентификаторы, поскольку они выходят из одного и того же суперкласса.Вот почему я получаю исключение

... Repeated column in mapping for entity ...

. Может помочь решить эту проблему, сохранив дизайн наследования.

Примечание. Сгенерированный класс из relashionship имеет дополнительные атрибуты.

Java-классы

Персона

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "PERSON")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="discriminator",
    discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue(value="P")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PERSON_ID")
    protected int personId;
    @Column(name = "PERSON_FIRST_NAME")
    protected String personFirstName;
    @Column(name = "PERSON_LAST_NAME")
    protected String personLastName;
    @Column(name = "PERSON_EMAIL")
    protected String personEmail;
    @Column(name = "PERSON_IMAGE")
    protected String personImage;

    // Constructors and Getter/Setter methods,
    public Person() {
    }

    /**
     * @param personId
     * @param personFirstName
     * @param personLastName
     * @param personEmail
     * @param personImage
     */
    public Person(String personFirstName, String personLastName, String personEmail, String personImage) {
        this.personFirstName = personFirstName;
        this.personLastName = personLastName;
        this.personEmail = personEmail;
        this.personImage = personImage;
    }

    public int getPersonId() {
        return personId;
    }

    public void setPersonId(int personId) {
        this.personId = personId;
    }

    public String getPersonFirstName() {
        return personFirstName;
    }

    public void setPersonFirstName(String personFirstName) {
        this.personFirstName = personFirstName;
    }

    public String getPersonLastName() {
        return personLastName;
    }

    public void setPersonLastName(String personLastName) {
        this.personLastName = personLastName;
    }

    public String getPersonEmail() {
        return personEmail;
    }

    public void setPersonEmail(String personEmail) {
        this.personEmail = personEmail;
    }

    public String getPersonImage() {
        return personImage;
    }

    public void setPersonImage(String personImage) {
        this.personImage = personImage;
    }

}

Менеджер

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;


@Entity
@Table(name="PERSON")
@DiscriminatorValue("M")
public class Manager extends Person implements Serializable{

    @Column(name="Budget")
    private double budget;

    @OneToMany( fetch = FetchType.LAZY, mappedBy="manager",
            cascade=CascadeType.ALL)
    private List<Meeting> listAppointment;

    public Manager() {
        super();
    }


    public Manager(String personFirstName, String personLastName, String personEmail, String personImage, double budget) {
        super(personFirstName, personLastName, personEmail, personImage);
        this.budget=budget;
    }

    public double getBudget() {
        return budget;
    }


    public void setBudget(double budget) {
        this.budget = budget;
    }

    //meeting
    public List<Meeting> getListAppointment() {
        if (listAppointment == null)
            listAppointment = new ArrayList<>();
        return listAppointment;
    }

    public Iterator<Meeting> getIteratorAppointment() {
        if (listAppointment == null)
            listAppointment = new ArrayList<>();
        return listAppointment.iterator();
    }


    public void setListAppointment(List<Meeting> newListAppointment) {
        removeAllAppointment();
        for (Iterator<Meeting> iter = newListAppointment.iterator(); iter.hasNext();)
            addAppointment(iter.next());
    }

    public void addAppointment(Meeting newAppointment) {
        if (newAppointment == null)
            return;
        if (this.listAppointment == null)
            this.listAppointment = new ArrayList<>();
        if (!this.listAppointment.contains(newAppointment)) {
            this.listAppointment.add(newAppointment);
            newAppointment.setDoctor(this);
        }
    }

    public void removeAppointment(Meeting oldAppointment) {
        if (oldAppointment == null)
            return;
        if (this.listAppointment != null && this.listAppointment.contains(oldAppointment)) {
            this.listAppointment.remove(oldAppointment);
            oldAppointment.setDoctor(null);
        }
    }

    public void removeAllAppointment() {
        if (listAppointment != null) {
            Meeting oldAppointment;
            for (Iterator<Meeting> iter = getIteratorAppointment(); iter.hasNext();) {
                oldAppointment = iter.next();
                iter.remove();
                oldAppointment.setDoctor(null);
            }
        }
    }
    // End Meeting

}

Сотрудник

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;


@Entity
@Table(name = "PERSON")
@DiscriminatorValue("E")
public class Employee extends Person implements Serializable {


    @OneToMany( fetch = FetchType.LAZY, mappedBy="employee",
            cascade=CascadeType.ALL)
    private List<Meeting> listAppointment;

    public Employee() {
        super();
    }

    public Employee(String personFirstName, String personLastName, String personEmail, String personImage) {
        this.personFirstName = personFirstName;
        this.personLastName = personLastName;
        this.personEmail = personEmail;
        this.personImage = personImage;
    }

}

Meeting.java

@Entity
@Table(name = "MEETING")
public class Meeting implements Serializable{
@Id
@GeneratedValue
@Column(name = "MEETING_ID")
private long id;

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "PERSON_ID") 
private Manager manager;

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "PERSON_ID")  
private Employee employee;

// additional fields
private boolean activated;
private Date registeredDate;

public Meeting() {
}

public Meeting(Manager manager, Employee employee) {
    this.manager = manager;
    this.employee = employee;
    this.id= Long.parseLong(String.valueOf(manager.getPersonId()).concat(String.valueOf(employee.getPersonId())));
}

Исключение Java

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1710) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1085) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:858) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.gestion.GestionCliniqueApplication.main(GestionCliniqueApplication.java:10) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:970) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:895) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:388) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    ... 15 common frames omitted
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: org.gestion.modele.Meeting column: person_id (should be mapped with insert="false" update="false")
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:835) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:853) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:875) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:607) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:265) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:459) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    ... 22 common frames omitted

Ответы [ 3 ]

0 голосов
/ 21 мая 2018

Fisrst , я думаю, вы должны изменить InheritanceType для класса Person

@Inheritance(strategy = InheritanceType.JOINED)

Second , добавить идентификатор для класса Employee и Manager.

0 голосов
/ 11 июня 2018

Я исправил проблему, добавив:

targetEntity= Manager.class

и удалив:

@JoinColumn(name = "PERSON_ID")

См. Код ниже:

    import java.io.Serializable;
    import java.util.Date;

    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;

    @Entity
    @Table(name = "MEETING")
    public class Meeting implements Serializable{
        @Id
        @GeneratedValue
        @Column(name = "MEETING_ID")
        private long id;

        @ManyToOne(cascade = CascadeType.ALL, targetEntity= Manager.class)
        private Manager manager;

        @ManyToOne(cascade = CascadeType.ALL, targetEntity = Employee.class)
        private Employee employee; 

        // additional fields
        private boolean activated;
        private Date registeredDate;

        public Meeting() {
        }

        public Meeting(Manager manager, Employee employee) {
            this.manager = manager;
            this.employee = employee;
            this.id= Long.parseLong(String.valueOf(manager.getPersonId()).concat(String.valueOf(employee.getPersonId())));
        }


        public long getId() {
            return id;
        }

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


        public Manager getDoctor() {
            return manager;
        }

        public void setDoctor(Manager manager) {
            this.manager = manager;
        }


        public Employee getClient() {
            return employee;
        }

        public void setClient(Employee employee) {
            this.employee = employee;
        }

        public boolean isActivated() {
            return activated;
        }

        public void setActivated(boolean activated) {
            this.activated = activated;
        }

        @Column(name = "REGISTERED_DATE")
        @Temporal(TemporalType.DATE)
        public Date getRegisteredDate() {
            return registeredDate;
        }

        public void setRegisteredDate(Date registeredDate) {
            this.registeredDate = registeredDate;
        }
    }
0 голосов
/ 21 мая 2018

Изменить имя сопоставления столбцов.Например, от:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "PERSON_ID") 
private Manager manager;

С чем-то вроде:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "PERSON_AS_MNGR_ID") 
private Manager manager;

HTH

...