Spring MVC 和 Hibernate 中带有附加列的多对多关系和复合主键

Many to Many relationship and composite primary key with additional column in Spring MVC and Hibernate

我正在开发一个接受客户订单的系统。 在系统中有以下classes.

class product{

private Integer productId;
//other attributes and methods

}

class OrderDetail{

private Integer orderId;
//other attributes and methods

}

OrderDetail 可以有很多产品,product 可以有很多订单。 我还想知道订单中每种产品的数量。 所以我想要这个.....

order_id |  product_id  | quantity_of_each_product  | 
    1    |      A1      |    10
    1    |      B1      |    08
    2    |      A1      |    04
    2    |      B1      |    04

我想要一个这样的table....

我参考了一个例子并为table.It创建了一个新的主键是OrderProductId class。然后我创建一个名为 OrderProduct.

的新实体 class

我也在使用 JpaRepository class 连接 DB

这就是我做的.....(所有代码)

//this is my order class
@Entity
public class OrderDetail {

    @Id
    @GeneratedValue
    private Integer orderId;

//this is how I map with OrderProduct class
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.orderDeatail", cascade=CascadeType.ALL)
    Set<OrderProduct> orderProduct = new HashSet<OrderProduct>();

}



//this is mys product class
@Entity
public class Product {

    @Id
    @GeneratedValue
    private Integer id;
//this is how I map with OrderProduct class
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.product", cascade=CascadeType.ALL)
    Set<OrderProduct> orderProduct = new HashSet<OrderProduct>();

}


//this is my new primary key class

@Embeddable
public class OrderProductId implements Serializable {

    @ManyToOne
    private Product product;
    @ManyToOne
    private OrderDetail detail;

}

// this is my new entity class

@Entity
@Table(name = "order_product_quntity")
@AssociationOverrides({
        @AssociationOverride(name = "pk.orderDeatail", 
            joinColumns = @JoinColumn(name = "ORDER_ID")),
        @AssociationOverride(name = "pk.product", 
            joinColumns = @JoinColumn(name = "PRODUCT_ID")) })
public class OrderProduct {

    private OrderProductId primaryKey = new OrderProductId();

    @Column(name = "Quntity")
    private Integer quntity;

    @EmbeddedId
    public OrderProductId getPrimaryKey() {
        return primaryKey;
    }

    public void setPrimaryKey(OrderProductId primaryKey) {
        this.primaryKey = primaryKey;
    }

    public Integer getQuntity() {
        return quntity;
    }

    public void setQuntity(Integer quntity) {
        this.quntity = quntity;
    }   
}

这是我的 applicationContext.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:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

    <context:component-scan base-package="com.nought">
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="emf">
        <property name="packagesToScan" value="com.nought.entity" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            </props>
        </property>
        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/hibernate" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <import resource="security.xml"/>

    <tx:annotation-driven transaction-manager="transactionManager" />

    <mvc:annotation-driven />

    <jpa:repositories base-package="com.nought.repository"
        entity-manager-factory-ref="emf" />

</beans>

当我构建项目时出现此错误......

2015-04-21 20:46:36.610:WARN:oejw.WebAppContext:main: Failed startup of context o.e.j.m.p.JettyWebAppContext@4f668f29{/,file:///C:/Users/Nought/workspace/luna/thelaststand/src/main/webapp/,STARTING}{file:///C:/Users/Nought/workspace/luna/thelaststand/src/main/webapp/}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emf' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
.......
.......
.......
Caused by: 
javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
......
......
......
Caused by: 
org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.nought.entity.OrderProduct.pk.product in com.nought.entity.Product.orderProduct

我对大局还不是很清楚,但我觉得替换:

... "pk.orderDeatail" ...
... "pk.product" ...

作者:

... "primaryKey.order" ...
... "primaryKey.product" ...

在所有情况下...可以在错误消息方面改进我们。 或者,您可以将 primaryKey (+getter/setter) 重命名为 pk