Hibernate, Spring Framework и многие ко многим - PullRequest
0 голосов
/ 08 января 2020

Не могли бы вы помочь мне с простым примером отношения многих ко многим, используя Spring ( framework NOT BOOT OR * MVC) и Hibernate. У меня есть два класса Users и Courses, и мне нужна промежуточная таблица (class) UserCourse. Я не могу использовать аннотации @ManyToMany, потому что мне нужно добавить дополнительные столбцы в свою промежуточную таблицу, поэтому мне нужно сделать что-то вроде этого: https://examples.javacodegeeks.com/enterprise-java/hibernate/hibernate-many-to-many-relationship-with-join-table-example/ Не могли бы вы объяснить, как включить пружину в это , Я пытался что-то, но я получил эту ошибку:

ПРЕДУПРЕЖДЕНИЕ: во время инициализации контекста возникла исключительная ситуация - отмена refre sh попытка: org.springframework.beans.factory.UnsatisfiedDependencyException: ошибка создания бина с именем 'cursDAOImpl': неудовлетворен зависимость выражается через поле 'sessionFactory'; вложенное исключение - org.springframework.beans.factory.BeanCreationException: ошибка создания бина с именем 'sessionFactory', определенным в ресурсе пути к классу [spring.xml]: сбой вызова метода init; вложенным исключением является org.hibernate.AnnotationException: mappedBy ссылается на неизвестное целевое свойство объекта: com.proiect.persistence.entity.UserCurs.pk.curs в com.proiect.persistence.entity.Curs.usercurs Исключение в потоке «main» org. springframework.beans.factory.UnsatisfiedDependencyException: Ошибка создания компонента с именем 'cursDAOImpl': Неудовлетворенная зависимость, выраженная через поле 'sessionFactory'; вложенное исключение - org.springframework.beans.factory.BeanCreationException: ошибка создания бина с именем 'sessionFactory', определенным в ресурсе пути к классу [spring.xml]: сбой вызова метода init; вложенным исключением является org.hibernate.AnnotationException: mappedBy ссылается на неизвестное целевое свойство сущности: com.proiect.persistence.entity.UserCurs.pk.curs в com.proiect.persistence.entity.Curs.usercurs в org.springframework.beans.factory .annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor. java: 586) в org.springframework.beans.factory.annotation.InjectionMetadata. (. AutowiredAnnotationBeanPostProcessor java: 364) .AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues ​​на org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (. AbstractAutowireCapableBeanFactory java 1269) в org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory. java: 551) в org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBea n (AbstractAutowireCapableBeanFactory. java: 481) в org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject (AbstractBeanFactory. java: 312) в org.springframework.beanstoneng . java: 230) в org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory. java: 308) в org.springframework.beans.factory.support.AbstractBeanFactory.beB 10 (. : 197) в org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory. java: 761) в org.springframework.context.support.AbstractApplicationContext. springframework.context.support.AbstractApplicationContext.refre sh (AbstractApplicationContext. java: 543) в org.springframework.context.support.ClassPathXmlApplicationContext. (ClassPathXmlApplicationContext. * 1038) * 1038 ) в org.springframework.context.support.ClassPathXmlApplicationContext. (ClassPathXmlApplicationContext. java: 83) в Application.main (Application. java: 23). Вызывается: org.springframework.beans.factory.BeanCreationException: ошибка с именем 'sessionFactory', определенным в ресурсе пути к классу [spring. xml]: сбой вызова метода init; вложенным исключением является org.hibernate.AnnotationException: mappedBy ссылается на неизвестное целевое свойство сущности: com.proiect.persistence.entity.UserCurs.pk.curs в com.proiect.persistence.entity.Curs.usercurs в org.springframework.beans.factory .support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory java:. 1631) в org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory java:. 553) в org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory .createBean (AbstractAutowireCapableBeanFactory. java: 481) в org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject (AbstractBeanFactory. java: 312) в org.springfacts DefaultSingletonBeanRegistry. java: 230) в org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory. java: 308) в org.springframework.beans.f actory.support. DefaultListableBeanFactory. inject (AutowiredAnnotationBeanPostProcessor. java: 583) ... еще 15 причин: org.hibernate.AnnotationException: mappedBy ссылается на неизвестное свойство целевого объекта: com.proiect.persistence.entity.UserCurs.pk.curs в com.proiect. persistence.entity.Curs.usercurs at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass (CollectionBinder. java: 768) в org.hibernate.cfg.annotations.CollectionBinder $ 1.secondPass (Collection Binder. java: 728) в org.hibernate.cfg.CollectionSecondPass.doSecondPass (CollectionSecondPass. java: 70) в org.hibernate.cfg.Configuration.originalSecondPassCompile (Конфигурация. java: 1695) в org.hiber. .cfg.Configuration.secondPassCompile (Configuration. java: 1424) в org.hibernate.cfg.Configuration.buildSessionFactory (Configuration. java: 1844) в org.hibernate.cfg.Configuration.buildSessionFactory (Configuration. java). : 1928) в org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory (LocalSessionFactoryBuilder. java: 372) в org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFraf. orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet (LocalSessionFactoryBean. java: 439) в org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. AbstractAuto wireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory. java: 1627) ... еще 25

@Entity
@Table(name="user")
public class User implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer user_id;

    @Column(name="username")
    private String username;

    @Column(name="firstname")
    private String firstname;

    @Column(name="lastname")
    private String lastname;

    @Column(name="password")
    private String password;

    @Column(name="email")
    private String email;


    @OneToMany(fetch = FetchType.LAZY,mappedBy = "pk.user",cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST})
    private Set<UserCurs> usercurs = new HashSet<UserCurs>(); 

    public Integer getUser_id() {
        return user_id;
    }

    public void setUser_id(Integer user_id) {
        this.user_id = user_id;
    }

    public String getUsername() {
        return username;
    }


    public void setUsername(String username) {
        this.username = username;
    }


    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }


    public Set<UserCurs> getUsercurs() {
        return usercurs;
    }

    public void setUsercurs(Set<UserCurs> usercurs) {
        this.usercurs = usercurs;
    }

и вот моя сущность курса

        package com.proiect.persistence.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
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.Table;


@Entity
@Table(name = "curs")
public class Curs implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer curs_id;

    @Column(name = "denumire")
    private String denumire;


    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.curs")
    private Set<UserCurs> usercurs = new HashSet<UserCurs>();

    public Curs() {
    }

    public Curs(String denumire) {
        this.denumire = denumire;
    }



    public Integer getCurs_id() {
        return curs_id;
    }

    public void setCurs_id(Integer curs_id) {
        this.curs_id = curs_id;
    }

    public String getDenumire() {
        return denumire;
    }

    public void setDenumire(String denumire) {
        this.denumire = denumire;
    }

    public Set<UserCurs> getUsercurs() {
        return usercurs;
    }


    public void setUsercurs(Set<UserCurs> usercurs) {
        this.usercurs = usercurs;
    }

    @Override
    public String toString() {
        return "Curs [curs_id=" + curs_id + ", denumire=" + denumire + ", usercurs=" + usercurs + "]";
    }


}

И там я попытался соединить эти классы через UserCurs

package com.proiect.persistence.entity;

import java.beans.Transient;

import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;

@Entity
@Table(name="user_curs")
@AssociationOverrides({
    @AssociationOverride(name="pk.user", joinColumns = @JoinColumn(name="user_id")),
    @AssociationOverride(name="pk.curs", joinColumns = @JoinColumn(name="curs_id"))
})
public class UserCurs implements java.io.Serializable {

    private static final long serialVersionUID = 4050660680047579957L;

    private UserCursID pk = new UserCursID();

    @EmbeddedId
    public UserCursID getPk() {
        return pk;
    }

    @Transient
    public User getUser() {
        return getPk().getUser();
    }

    public void setUser(User user) {
        getPk().setUser(user);
    }

    @Transient
    public Curs getCs() {
        return getPk().getCs();
    }

    public void setCs(Curs c) {
        getPk().setCs(c);
    }

    public void setPk(UserCursID pk) {
        this.pk = pk;
    }

}

UserCursID:

package com.proiect.persistence.entity;

import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;

@Embeddable
public class UserCursID implements java.io.Serializable {

    private static final long serialVersionUID = -9120607274421816301L;

    @ManyToOne
    private User user;
    @ManyToOne
    private Curs cs;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public Curs getCs() {
        return cs;
    }
    public void setCs(Curs cs) {
        this.cs = cs;
    }   

}

А это моя весна. xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd ">


    <context:property-placeholder
        location="classpath:database.properties" />

    <context:component-scan
        base-package="com.proiect.persistence.dao"></context:component-scan>
    <tx:annotation-driven />


    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"
            value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>


    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <value>com.proiect.persistence.entity</value>
            </list>
        </property>

        <property name="annotatedClasses">
            <list>

            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql:true}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>

            </props>
        </property>
    </bean>



    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:annotation-driven />

    <bean id="persistenceExceptionTranslationPostProcessor"
        class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

</beans>

1 Ответ

1 голос
/ 08 января 2020

Первое предложение - неправильное сопоставление между свойствами имени, например

@AssociationOverrides({
    @AssociationOverride(name="pk.user", joinColumns = @JoinColumn(name="user_id")),
    @AssociationOverride(name="pk.curs", joinColumns = @JoinColumn(name="curs_id"))
})

Вы переопределяете отношение для pk.curs , которое должно соответствовать имени поля curs класса UserCursID. Но у вас есть

@ManyToOne
    private Curs cs;

Попробуйте сделать их последовательными.

...