0

私はSpringでHibernate4.1.7Javaを使用しており、MySqlに取り組んでいます。

抽象で3つのサブクラスを持つPublicationクラスと、抽象で2つのサブクラスを持つPageクラスがあります。

パブリケーションにはリストがあり、ページにはパブリケーションがあるので、これは一般的なOneToMany / ManyToOne双方向関係ですが、ページを並べ替える必要があるため、次のようにクロステーブルを使用しています。

// Publication.java
@OneToMany(fetch=FetchType.LAZY)
@JoinTable(name="publication_pages",
            joinColumns=@JoinColumn(table="publication_pages", name="pub_id", referencedColumnName="id"),
            inverseJoinColumns=@JoinColumn(table="publication_pages", name="pg_id", referencedColumnName="id"))
@OrderColumn(name="i")
public List<Page> getPages() {
    return pages;
}

// Page.java

@ManyToOne
@JoinTable(name="publication_pages",
        joinColumns=@JoinColumn(table="publication_pages", name="pg_id", referencedColumnName="id", insertable=false, updatable=false),
        inverseJoinColumns=@JoinColumn(table="publication_pages", name="pub_id", referencedColumnName="id", insertable=false, updatable=false))
public Publication getPublication() {
    return publication;
}

Hibernateはアノテーションについて文句を言いませんが、getPagesを呼び出そうとするとすぐに、クロステーブルだけでなく、Pageサブクラステーブルでpub_idを検索するクエリが生成されます。

エラーは次のとおりです。

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'page1_.pub_id' in 'field list'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1053)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4006)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2468)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2318)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy54.executeQuery(Unknown Source)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1897)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1698)
at org.hibernate.loader.Loader.doQuery(Loader.java:832)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:293)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:263)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2094)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:61)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:678)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:82)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1801)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:524)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:212)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:520)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:125)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:152)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:139)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:212)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:138)
at org.hibernate.collection.internal.PersistentList.isEmpty(PersistentList.java:121)

私は何か間違ったことをしているのですか、それともHibernateのバグですか、それともクエリで実行する結合の数が多いために単純に不可能ですか?

TIA

編集:これはHibernateが生成しているクエリです(関連のない列をすべて削除しました):

Hibernate: 
select 
pages0_.pub_id as pub1_46_3_, 
pages0_.pg_id as pg2_43_3_, 
pages0_.i as i3_,
page1_.id as id42_0_, 
[...] 
page1_.pub_id as pub1_43_0_ [...]

from publication_pages pages0_ 
inner join ( 
  select id, [...] from page_fixed union select id, [...] from page_query 
) page1_

on pages0_.pg_id=page1_.id left outer join ( 
  select id, [...] from publication 
) publicatio2_ 
on page1_.pub_id=publicatio2_.id left where pages0_.pub_id=?

ご覧のとおり、pages0_.pub_id(where句で正しく使用されている)ではなく、(pub_idがPageにあるかのように)結合でpage1_.pub_idを使用します。

これは、Publication.getPages()。isEmpty()の呼び出しで発生します

4

1 に答える 1

0

たぶん、あなたはあなたにを追加し、そのを削除することができmappedByます。OneToMany / ManyToOneとの双方向の関係は、両側で必要ではなく、関係の所有者でのみ必要です。@OneToMany@JoingTable@JoingTable

于 2013-03-15T18:23:08.417 に答える