2013-11-14 6 views
0

Я использую ServiceMix с Apache Felix, а мое Enterprise Application состоит из нескольких пакетов. Например, у меня есть пакет с моими сущностными классами jpa и еще один пакет с бизнес-логикой и dao-классами. Из-за того, что я использую OpenJPA, для проекта entity-bundle нужен файл persistenc.xml в папке META-INF для инкапсуции байт-кода в compiletime, но этот пакет предоставляет блок персистентности заголовком Meta-Persistence в манифесте пакета. Внутри дао обеспечения расслоения я впрыснуть менеджер сущностей с помощью blueprint.xml:OSGi с использованием единицы непрерывности jpa из другого пакета?

<bean id="systemUserDAOBean" class="server.daos.SystemUserDAO"> 
    <tx:transaction method="*" value="Required" /> 
    <jpa:context property="entityManager" unitname="mypu" /> 
</bean> 

, если я позвоню во время выполнения следующий метод из дао:

public SystemUser readSystemUser(String username) { 
     final EntityManager em = getEntityManager(); 
     final Query q = em.createQuery("select a from SystemUser a where a.username = '"+username+"'"); 
     return (SystemUser) q.getSingleResult(); 
} 

ClassCastException будет выброшено:

java.lang.ClassCastException: mypackage.SystemUser не может быть приведен к mypackage.SystemUser

То, что я выяснил до сих пор, заключается в том, что загрузчик классов, который загружал класс возвращаемого объекта entitymanager, отличается от загрузчика классов, который загружает возвращаемый тип метода. Может быть, первый загрузчик классов - это загрузчик классов для пакета объектов, а второй - загрузчик классов dao, предоставляющий пакет?

Если я скопирую persistence.xml в DAO-Bundle и использую его блок персистентности в файле blueprint.xml, исключение ClassCastException не будет выбрано. Но в этом случае у меня есть два одинаковых файла persistence.xml внутри одного и того же приложения, чего я не хочу. :(

ли кто-нибудь есть идеи, как решить эту проблему

спасибо, Phill

EDIT: Когда я перезапустить ServiceMix исключение прошло, пока я не обновлю сверток настойчивости и я узнал. , что оба загрузчика классов взяты из набора персистентности.

ответ

0

Похоже, вы скопировали классы домена (включая, я предполагаю, SystemUser) в несколько пакетов. Вы не должны этого делать, потому что, как вы обнаружили, Java рассматривает тот же класс, загруженный различными ClassLoaders, для разных классов, и, следовательно, вы получаете ClassCastException.

Вы должны экспортировать пакет домена из одного пакета, используя заголовок Export-Package. Вероятно, это должно быть сделано из вашего набора персистентности. Все остальные пакеты должны импортировать этот пакет.

+0

Нет никаких копируемых классов. Только мой «пакет persistence-bundle» предоставляет все классы сущностей (Export-Package). –

+0

Извините, я не могу предложить никаких дополнительных советов, кроме как продолжать искать это дублирование. Когда вы видите ошибку «ClassCastException: X не может быть отброшена в X», она всегда * означает, что класс X был загружен отдельно двумя разными загрузчиками классов (в Java идентификатор класса представляет собой комбинацию его полностью квалифицированного имени * и * загрузчик классов, который загрузил его). –