hibernate サイトにある hibernate_reference.pdf を使用して、Hibernate 多対多関連付けを使用しています。ドキュメントで説明されているように、同じエンティティ Event.java と Person.java を使用しています。
多くの人が「コレクションの例外を初期化できませんでした」と直面しているのを見て、多くの人が問題に対処しましたが、スタックオーバーフローの投稿に記載されている解決策はどれも私の問題を解決しませんでした。これらのソリューションが多対多の関連付けで機能しないか、構成に問題がある可能性があります。以下は私の hbm.xml ファイルです:
Event.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 package="roseindia.tutorial.hibernate">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="native" />
</id>
<property name="date" type="timestamp" column="EVENT_DATE" />
<property name="title" type="string" />
<property name="location" type="string" column="LOC" />
<set name="participants" table="PERSON_EVENT" inverse="true" lazy="false" cascade="all" >
<key column="EVENT_ID" not-null="true" />
<many-to-many column="PERSON_ID" class="Person" />
</set>
</class>
</hibernate-mapping>
イベント.java
public class Event implements java.io.Serializable {
private long id;
private String title;
private Date date;
private String location;
public Event() {
//participants = new HashSet<Person>(0);
}
private Set participants = new HashSet(0);
public Set getParticipants() {
return participants;
}
public void setParticipants(Set participants) {
this.participants = participants;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((date == null) ? 0 : date.hashCode());
//result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result
+ ((location == null) ? 0 : location.hashCode());
//result = prime * result + ((participants == null) ? 0 : participants.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Event other = (Event) obj;
if (date == null) {
if (other.date != null)
return false;
} else if (!date.equals(other.date))
return false;
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
@SuppressWarnings("unchecked")
public void addToParticipants(Person person) {
this.getParticipants().add(person);
//person.addToEvent(this);
person.getEvents().add(this);
}
public void removeFromParticipants(Person person) {
this.getParticipants().remove(this);
person.getEvents().remove(person);
}
public long getId() {
return id;
}
private void setId(long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLocation() {
return this.location;
}
public void setLocation(String location) {
this.location = location;
}
}
Person.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 package="roseindia.tutorial.hibernate">
<class name="Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="native" />
</id>
<property name="age" />
<property name="firstname" />
<property name="lastname" />
<set name="events" table="PERSON_EVENT" inverse="false" lazy="true" cascade="all" >
<key column="PERSON_ID" not-null="true" />
<many-to-many column="EVENT_ID" class="Event" />
</set>
<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
<key column="PERSON_ID" />
<element type="string" column="EMAIL_ADDR" />
</set>
</class>
</hibernate-mapping>
Person.java
import java.util.HashSet;
import java.util.Set;
public class Person implements java.io.Serializable {
private Set events = new HashSet<Event>();
private Set emailAddresses = new HashSet();
public Set getEmailAddresses() {
return emailAddresses;
}
public void setEmailAddresses(Set emailAddresses) {
this.emailAddresses = emailAddresses;
}
public void addToEvent(Event event) {
this.getEvents().add(event);
//event.addToParticipants(this);
event.getParticipants().add(this);
}
public void removeFromEvent(Event event) {
this.getEvents().remove(event);
//event.removeFromParticipants(this);
event.getParticipants().remove(this);
}
public Set getEvents() {
return events;
}
public void setEvents(Set events) {
this.events = events;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getAge() {
return age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result
+ ((firstname == null) ? 0 : firstname.hashCode());
result = prime * result
+ ((lastname == null) ? 0 : lastname.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (firstname == null) {
if (other.firstname != null)
return false;
} else if (!firstname.equals(other.firstname))
return false;
if (lastname == null) {
if (other.lastname != null)
return false;
} else if (!lastname.equals(other.lastname))
return false;
return true;
}
public void setAge(int age) {
this.age = age;
}
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;
}
private Long id;
private int age;
private String firstname;
private String lastname;
public Person() {
}
}
ManyToManyExample.java
public class ManyToManyExample {
/**
* @param args
*/
public static void main(String[] args) {
Session session = null;
try {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
session = sessionFactory.openSession();
Transaction tx1 = session.beginTransaction();
System.out.println("Loading Record");
Event theEvent = (Event) session.get(Event.class, new Long(1));
session.refresh(theEvent);
Person person = new Person();
person.setAge(31);
person.getEvents().add(theEvent);
person.setFirstname("RRRRRR");
person.setLastname("NNNNNN");
person.getEmailAddresses().add("RRRRRR@yahoo.com");
theEvent.getParticipants().add(person); // Adding person ref. to event for many to many relation
session.save(theEvent);
session.save(person);
tx1.commit();
System.out.println("Done...");
} catch (Exception e) {
e.printStackTrace();
} finally {
session.flush();
session.close();
}
}
}
上記のサンプルを実行すると、次のエラーが発生します。 .exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:82) org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:70) で org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) で org. hibernate.loader.Loader.loadCollection(Loader.java:1351) org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:101) org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java: 484) org.hibernate.event.def で。DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60) org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1346) org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:269) org.hibernate.engine org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:208) の .PersistenceContext.initializeNonLazyCollections(PersistenceContext.java:745) org.hibernate.loader.Loader.loadEntity(Loader.java:1255) の org.hibernate. org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:124) の loader.entity.EntityLoader.load(EntityLoader.java:139) org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java: 2453) org.hibernate.event.def で。org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:368) で DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:387) org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:166) で org org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:249) の .hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:140) org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener) .java:123) で org.hibernate.impl.SessionImpl.get(SessionImpl.java:561) で org.hibernate.impl.SessionImpl.get(SessionImpl.java:556) で roseindia.tutorial.hibernate.ManyToManyExample.main( ManyToManyExample.java:24) 原因: java.sql.SQLException:[Microsoft][ODBC SQL Server Driver]sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6956) で無効な記述子インデックス.odbc.JdbcOdbc.SQLGetDataDouble(JdbcOdbc.java:3656)、sun.jdbc.odbc.JdbcOdbcResultSet.getDataDouble(JdbcOdbcResultSet.java:5574)、sun.jdbc.odbc.JdbcOdbcResultSet.getLong(JdbcOdbcResultSet.java:632)。 jdbc.odbc.JdbcOdbcResultSet.getLong(JdbcOdbcResultSet.java:650) org.hibernate.type.LongType.get(LongType.java:26) org.hibernate.type.NullableType.nullSafeGet(NullableType.java:77) org .hibernate.type.NullableType.nullSafeGet(NullableType.java:68) org.hibernate.persister.collection.AbstractCollectionPersister.readKey(AbstractCollectionPersister.java:612) org.hibernate.loader.Loader.readCollectionElement(Loader.java:545) の org.hibernate.loader.Loader.readCollectionElements(Loader.java:344) の org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:299) の org.hibernate.loader.Loader .doQuery(Loader.java:384) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:203) at org.hibernate.loader.Loader.loadCollection(Loader.java:1344) ... 20 以上
person オブジェクトを作成し、session.get(...) を使用してイベントをフェッチしてイベントを追加します。多対多の関係の場合、すべてのオブジェクトを人物のイベント リストに追加した後、別の方法でイベント オブジェクトの参加者リストに人物を追加すると、例外がスローされます。どんな助けや指導も大歓迎です!
データベースとして SQL Server 2008 を使用しています。