Grails でプロキシされたオブジェクトに問題があります。私は次のものを持っていると仮定します
class Order {
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name="xxx", joinColumns = {@JoinColumn(name = "xxx")}, inverseJoinColumns = {@JoinColumn(name = "yyy")})
@OrderBy("id")
@Fetch(FetchMode.SUBSELECT)
private List<OrderItem> items;
}
class Customer {
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "xxx",insertable = false, nullable = false)
private OrderItem lastItem;
private Long lastOrderId;
}
そして、いくつかのコントローラークラス内
//this all happens during one hibernate session.
def currentCustomer = Customer.findById(id)
//at this point currentCustomer.lastItem is a javassist proxy
def lastOrder = Order.findById(current.lastOrderId)
//lastOrder.items is a proxy
//Some sample actions to initialise collections
lastOrder.items.each { println "${it.id}"}
反復後lastOrder.items
も のプロキシが含まれていますcurrentCustomer.lastItem
。たとえば、lastOrder.items コレクションに 4 つのアイテムがある場合、次のようになります。
- 物体
- 物体
- javassist プロキシ (id フィールドを含むすべてのフィールドが null です)。これは currentCustomer.lastItem と同じオブジェクトです。
- 物体
さらに、このプロキシ オブジェクトはすべてのプロパティが null に設定されており、getter が呼び出されたときに初期化されません。内部にプロキシがないことを確認するために、GrailsHibernateUtils.unwrapIdProxy()
内部のすべての要素を手動で呼び出す必要があります (これは基本的に EAGER フェッチにつながります)。lastOrder.items
この 1 つのプロキシ オブジェクトは、テスト フェーズで追跡するのが困難ないくつかの非常に奇妙な例外につながります。
興味深い事実: 操作の順序を変更すると (注文を最初にロードし、顧客を 2 番目にロードする)、内部のすべての要素lastOrder.items
が初期化されます。
問題は、コレクションの要素がセッションですでにプロキシされているかどうかに関係なく、コレクションに触れたときにコレクションを初期化する必要があることを Hibernate に伝える方法はありますか?