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
。
我正在开发一个接受客户订单的系统。 在系统中有以下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
.
我也在使用 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
。