我正在从教程中学习休眠中的多体关系。我的示例项目有两个表,分别称为product_table和order_table。我正在使用这两个表之间的多对多关系。
在执行我的代码时,我在控制台中发现以下错误:
Exception in thread "main" org.hibernate.MappingException: Could not determine type for: java.util.Collection, at table: product_details, for columns: [org.hibernate.mapping.Column(orders)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:456)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:423)
at org.hibernate.mapping.Property.isValid(Property.java:226)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:597)
at org.hibernate.mapping.RootClass.validate(RootClass.java:265)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:459)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
at com.hibernatetest.main.MainApp.hibernateSession(MainApp.java:98)
at com.hibernatetest.main.MainApp.main(MainApp.java:93)
这是我的Hibernate配置文件:
<!-- ~ Hibernate, Relational Persistence for Idiomatic Java ~ ~ License:
GNU Lesser General Public License (LGPL), version 2.1 or later. ~ See the
lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- In case of using MySQL greater than 5 use MYSQL5 Dialect in stead of mysqldialect -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_test?createDatabaseIfNotExist=true</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping class="com.hibernatetest.dto.ProductDetails" />
<mapping class="com.hibernatetest.dto.OrderDetails" />
</session-factory>
</hibernate-configuration>
这是我的OrderDetails类:
package com.hibernatetest.dto;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name = "product_details")
public class ProductDetails {
private int productId;
private String productName;
@ManyToMany(mappedBy="product_details")
private Collection<OrderDetails> orders=new ArrayList();
public ProductDetails() {
}
public ProductDetails(String productName) {
this.productName = productName;
}
@Id
@Column(name = "product_id")
@GeneratedValue(strategy = GenerationType.AUTO)
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
@Column(name = "product_name")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Collection<OrderDetails> getOrders() {
return orders;
}
public void setOrders(Collection<OrderDetails> orders) {
this.orders = orders;
}
}
这是我的OrderDetails类:
package com.hibernatetest.dto;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "order_details")
public class OrderDetails {
private int orderId;
private String orderName;
@ManyToMany
private Collection<ProductDetails> products = new ArrayList();
public OrderDetails() {
super();
}
public OrderDetails(String orderName) {
super();
this.orderName = orderName;
}
@Id
@Column(name = "order_id")
@GeneratedValue(strategy = GenerationType.AUTO)
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
@Column(name = "order_name")
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Collection<ProductDetails> getProduct() {
return products;
}
public void setProduct(Collection<ProductDetails> products) {
this.products = products;
}
}
这是MainApp类:
package com.hibernatetest.main;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.hibernatetest.dto.Address;
import com.hibernatetest.dto.Office;
import com.hibernatetest.dto.OrderDetails;
import com.hibernatetest.dto.ProductDetails;
import com.hibernatetest.dto.UserDetails;
public class MainApp {
public static void main(String[] args) {
/*
* UserDetails user = new UserDetails(); UserDetails user2=new UserDetails();
* Address address1=new Address("test street1", "test city1", "test state",
* "0000"); Address address2=new Address("test street2", "test city2",
* "test state", "0001"); //user.setUserId(2); user.setUsername("Test User 1");
* user2.setUsername("Test User 2"); user.setJoinedDate(new Date());
* user2.setJoinedDate(new Date()); user.setHomeAddress(address1);
* user.setOfficeAddress(address2); user2.setHomeAddress(address2);
* user2.setOfficeAddress(address1); user.setDescription("test data 1");
* user2.setDescription("test data 2"); user.setJoinedTime(new Date());
* user2.setJoinedTime(new Date());
*
* String officePhone1="00000000"; String officePhone2="00000001"; String
* officePhone3="00000002"; Collection<String> phoneNumbers=new
* ArrayList<String>(); phoneNumbers.add(officePhone1);
* phoneNumbers.add(officePhone2); phoneNumbers.add(officePhone3); Office
* office=new Office(1,"Test Office 1", address1,phoneNumbers);
*
* SessionFactory sessionFactory = new
* Configuration().configure().buildSessionFactory();
*
* Session session = sessionFactory.openSession();
*
* session.beginTransaction();
*
* session.save(user); session.save(user2); session.save(office);
*
* session.getTransaction().commit();
*
* session.close();
*
* user=null;
*
* session= sessionFactory.openSession(); session.beginTransaction();
* user=session.get(UserDetails.class,2);
*
* System.out.println(user.getUserId()+" "+user.getDescription());
*
* session.close(); office=null; session=sessionFactory.openSession();
* session.beginTransaction(); office=session.get(Office.class, 1);
* System.out.println(office.getOfficeName()); session.close();
* System.out.println(office.getPhoneList().size());
*/
ProductDetails product1 = new ProductDetails("Sample product 1");
ProductDetails product2 = new ProductDetails("Sample product 2");
ProductDetails product3 = new ProductDetails("Sample product 3");
ProductDetails product4 = new ProductDetails("Sample product 4");
OrderDetails order1 = new OrderDetails("Order No 1");
OrderDetails order2 = new OrderDetails("Order No 2");
product1.getOrders().add(order1);
product1.getOrders().add(order2);
product2.getOrders().add(order2);
order1.getProduct().add(product1);
order1.getProduct().add(product2);
order1.getProduct().add(product3);
order2.getProduct().add(product1);
order2.getProduct().add(product3);
order2.getProduct().add(product4);
List<Object> insetableObjects = new ArrayList<Object>();
insetableObjects.add(product1);
insetableObjects.add(product2);
insetableObjects.add(product3);
insetableObjects.add(product4);
insetableObjects.add(order1);
insetableObjects.add(order2);
hibernateSession(insetableObjects);
}
public static void hibernateSession(List<Object> collection) {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
for (Object obj : collection) {
session.save(obj);
System.out.println("Object Added");
}
session.getTransaction().commit();
session.close();
}
}
请引导我进行下一步,并先谢谢您。
最佳答案
请参见this tutorial和Jack Flamp的注释。为了建立ManyToMany
关系,您需要一个@JoinTable
引用要在其特定类中使用的表,另一个引用。例如,在您的情况下,它将类似于:
产品详情:
@Entity
@Table(name = "product_details")
public class ProductDetails {
private int productId;
private String productName;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "order_product",
joinColumns = { @JoinColumn(name = "productId") },
inverseJoinColumns = { @JoinColumn(name = "orderId") }
)
private Collection<OrderDetails> orders = new ArrayList();
[...]
订单详细信息:
@Entity
@Table(name = "order_details")
public class OrderDetails {
private int orderId;
private String orderName;
@ManyToMany(mappedBy = "orders")
private Collection<ProductDetails> products = new ArrayList();
在这里,您的“拥有方”(即拥有信息的一方)就是产品。您的产品可以有多个订单,并且一个订单属于多个产品。当然,如果它不适合您的需求,请随意还原它们。我给您的链接很好地解释了每个注释的作用。
编辑:确保(在示例中)
order_product
表实际上存在。否则,它将无法正常工作。