0

JAX-RS を使用してオブジェクトを XML として公開しようとしています。

というクラスがClientあり、そのインスタンスを次のように返しています。

    @Transactional(readOnly=true)
    @GET
    @Produces("application/xml")
    @Path("/{clientId}.xml")
    public Client getCleintAsXML(@PathParam("clientId") int clientId) {
        Client c = em.find(Client.class, clientId);
        return c;
    }

ただし、ClientオブジェクトにはオブジェクトのリストがありGroupGroupオブジェクトには他のオブジェクトのリストがあります。

JAX-RS がオブジェクトをシリアライズしようとClientすると、オブジェクト グラフ全体が走査されます。groupsレイジーローディングはトランザクション内でのみ機能するため、Hibernate プロキシに遭遇するとコードが壊れます。

十分に公平なのでgroups、トランザクションを終了する前に熱心にロードします。

Groupしかし、各オブジェクトが 1 対多の関係、つまりさらにプロキシされたリストを持つため、それでも失敗します。

出力にそれらを必要としません。これらのプロキシが削除された場合、つまりnullに設定された場合、私の問題は解決されることを認識しています。

これはエラーが発生しやすく、保守できないため、手動で null に設定したくありません。これを自動的に行う方法はありますか?

または、この特定のクエリにプロキシを使用しないように hibernate に指示できますか? または、1 レベルの深さのプロキシのみを使用しますか?

JPAの背後でHibernateを使用しています。可能な限り、Hibernate への直接の参照は望んでいません。

プロキシを取り除くために、さまざまなユーザーによって作成された多数のクラスが見つかりました。これを行う標準的な方法はありますか?これが非常に一般的な問題である場合、標準的な解決策があると思います。

4

1 に答える 1

0

初期化されていない休止状態のプロキシを削除することで、この問題を解決しました。これは私の要件であったため、コレクションのみを削除します。他のユーザーの利益のために編集を自由に提案してください。

最初のカット:

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;

import org.apache.commons.beanutils.PropertyUtils;
import org.hibernate.Hibernate;
import org.hibernate.collection.PersistentCollection;
import org.springframework.beans.BeanUtils;

public class HibernateProxyCleaner {

    public static Object clean(Object bean) {
        return clean(bean,0,2);
    }

    public static Object clean(Collection bean, int depth, int maxDepth) {
        if (bean == null || depth>maxDepth)
            return bean;

        for (Object o : (Collection) bean) {
            clean(o,depth,maxDepth);
        }

        return bean;
    }

    public static Object clean(Object bean, int depth, int maxDepth) {
        if (bean == null || depth>maxDepth)
            return bean;

        try {
            PropertyDescriptor[] pda = BeanUtils.getPropertyDescriptors(bean
                    .getClass());

            for (PropertyDescriptor pd : pda) {
                Object o = PropertyUtils.getProperty(bean, pd.getName());
                if (o != null) {
                    if (o instanceof PersistentCollection) {
                        if (PropertyUtils.isReadable(bean, pd.getName()) && PropertyUtils.isWriteable(bean, pd.getName())) {
                            if (!Hibernate.isInitialized((PersistentCollection) o)) {
                                o = null;
                                PropertyUtils.setProperty(bean, pd.getName(), o);
                            }

                        }
                    } else {
                        clean(o,depth+1,maxDepth);
                    }
                }


            }
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return bean;
    }

}
于 2013-05-06T08:51:22.057 に答える