我正在做一个简单的Hibernate Java应用程序。我有两个主要的实体——学生和城市,通过多对一的关系(许多学生可以来自同一个城市)连接在一起。类别:
@Entity
@Table
public class Student {
@Id
@GeneratedValue
private int id;
private int indexNumber;
private String name;
private String familyName;
private ArrayList <Float> marks;
@ManyToOne
private City city;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public ArrayList<Float> getMarks() {
return marks;
}
public void setMarks(ArrayList<Float> marks) {
this.marks = marks;
}
public Student(int indexNumber, String name, String familyName,
ArrayList <Float> marks, City city) {
this.indexNumber = indexNumber;
this.name = name;
this.familyName = familyName;
this.marks = marks;
this.city = city;
}
public Student(){
}
public int getIndexNumber() {
return indexNumber;
}
public void setIndexNumber(int indexNumber) {
this.indexNumber = indexNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
@Override
public String toString()
{
return "Index number:"+indexNumber + "tttName:" + name + "tttFamily name:" + familyName + "tttMark:"+ getMarks()+"n";
}
}
城市:
@Entity
public class City {
@Id
@GeneratedValue
private int cityId;
private String name;
@OneToMany
private HashSet <Student> students = new HashSet <Student>(0);
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
public HashSet<Student> getStudents() {
return students;
}
public void setStudents(HashSet<Student> students) {
this.students = students;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public City()
{
}
public City(String name, HashSet <Student> students) {
super();
this.name = name;
this.students = students;
}
}
我的实体映射如下:
Student.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="michal.task2.Student" table="Student" catalog="db">
<id name="id" type="int">
<column name="id" />
<generator class="identity" />
</id>
<property name="indexNumber" type="int">
<column name="indexNumber" not-null="true" unique="true" />
</property>
<property name="name" type="string">
<column name="name" length="20" not-null="true"/>
</property>
<property name="familyName" type="string">
<column name="familyName" length="20" not-null="true"/>
</property>
<list name="marks">
<key column="mark" />
<list-index column="index" />
<element type="float"/>
</list>
<many-to-one name="city" class="michal.task2.City" fetch="select">
<column name="city" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
City.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="michal.task2.City" table="City"
catalog="db">
<id name="cityId" type="int">
<column name="cityId" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" not-null="true"/>
</property>
<set name="students" table="Student"
inverse="true" lazy="true" fetch="select">
<key>
<column name="studentId" not-null="true" />
</key>
<one-to-many class="michal.task2.Student" />
</set>
</class>
</hibernate-mapping>
问题是,当我调用将一个新学生添加到数据库的方法时:
public static void addStudent(Scanner sc) {
System.out.println("Define parameters of the new Student.n");
System.out.println("Index number:n");
int index = sc.nextInt();
System.out.println("Name:n");
sc.nextLine();
String name = sc.nextLine();
System.out.println("Family name:n");
String familyName = sc.nextLine();
System.out.println("Marks:n");
ArrayList <Float> marks = new ArrayList <Float>();
boolean go = true;
while(go){
System.out.println("Enter mark:n");
float mark = sc.nextFloat();
marks.add(mark);
System.out.println("Add another mark? 1-yes/2-non");
int choice = sc.nextInt();
if(choice == 2) go = false;
}
sc.nextLine();
System.out.println("City:n");
String cityName = sc.nextLine();
City city = new City();
city.setName(cityName);
Student student = new Student(index, name, familyName, marks, city);
city.getStudents().add(student);
session.beginTransaction();
session.save(city); //this line
session.save(student);
session.getTransaction().commit();
System.out.println("Student added!n");
}
在标记行,我得到一个非法参数异常,带有以下堆栈跟踪:
Exception in thread "main" org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of michal.task2.City.students
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:119)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:707)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:371)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4232)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:283)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:128)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:642)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:635)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:631)
at michal.task2.Main.addStudent(Main.java:93)
at michal.task2.Main.menu(Main.java:41)
at michal.task2.Main.main(Main.java:26)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:65)
... 17 more
实际上您的问题是由以下错误引起的:
Caused by: java.lang.IllegalArgumentException: argument type mismatch
请提供用于创建表的脚本,然后再次检查列类型。此外,将mappedBy
添加到此<one-to-many class="michal.task2.Student" mappedBy="city"/>
顺便说一句,尝试将xml配置更改为基于注释的配置,因为它更可读,更美观:)。