ClassCastException with spring-data-jpa - jboss

I'm working with Spring Web Services and Spring JPA Data.
I have three projects:
doc-ws. Web application that it's the endpoint of my documental web services.
sign-ws. Web application that it's the endpoint of my sign web services.
data-ws. Jar module with all the jpa entities (#Entity), spring jpa repositories (#Repository) and spring services classes (#Services).
Doc-ws and sign-ws has a dependence with data-ws, so a data-ws.jar is included in doc-ws.war and sign-ws.war.
When I deploy doc-ws web application alone, all the web services tests works fine.
When I deploy sign-ws web application alone, all the web services tests works fine.
But when I deploy both web applications together in the same Jboss EAP 7.1, I'm getting ClassCastExceptions when I exectute the web services tests.
java.lang.ClassCastException: com.ieci.mugeju.data.entity.IdocConfiguration cannot be cast to com.ieci.mugeju.data.entity.IdocConfiguration
List<IdocConfiguration> properties = idocConfigurationRepository.findAll(); <-- works fine
for (IdocConfiguration property: properties) <-- Here throws the ClassCastException
{
.... // CODE
}
Exception message reference the same jpa entity (com.ieci.mugeju.data.entity.IdocConfiguration), so I don't understand why this exception is being throwed.
It must be a classloading issue between both web applications, but I'm not sure.
I'm working with JBoss EAP 7.1, spring-data-jpa 2.0.5, eclipseling 2.6.4, spring-ws-core 3.0.1.
Any idea why I'm getting this exception? How could I solve?
Thanks

I discovered what the problem was. When I defined the 'entityManagerFactory', I was not setting the property called 'persistenceUnitName'. Then when the persistence context was created, it was created with the name 'default' in both web projects.
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="jpaDialect" ref="jpaDialect"/>
<property name="packagesToScan" value="com.ieci.mugeju.data.entity" />
...
</bean>
I don't know why but 'find repository methods' of second project return jpa entity classes defined in first project classloader. Very strange behaviour, I expected every web application using its own classloader, and isolated one from each other.
If I set a persistenceUnitName for every project, then everything works fine, and every web application uses its own classloader.
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="jpaDialect" ref="jpaDialect"/>
<property name="packagesToScan" value="com.ieci.mugeju.data.entity" />
<property name="persistenceUnitName" value="${spring.application.name}" />
...
</bean>

Related

JSF2 + Spring 4 + CDI + Spring Data, good match?

Let me tell you my story, and in between I will ask questions
I am working in a project I have to use JSF, there is not really other choice.
Coming from the wonderful Spring world in the last years, I really wanted to use some features like Spring Data, Spring singleton beans, Autowire beans into other beans, etc.
So I thought initially everything would be smooth, JSF (backing beans) will be managed by CDI container and #Service, #Respostory and database connection Entity manager by spring container. I want to make my application independent from a Java EE container, but just for information I am using Wildfly 9. In Wildfly, I create a datasource (connection to an oracle database) to bind later to my application.
So my first difficulty was, Some years ago, I code some JSF and I knew about #ManagedBean anotations and JSF scopes, all even though has not changed, there seems to be another aproach, and acording to what I read it is recommendable to use #Named and so on (CDI annotations) instead of the JSF annotations. So I wanted to follow those advices and somehow forces me to introduce CDI container into my application.
1st Question: Is that true ? Isn´t it recommendable to use old JSF annotations ?
My JSF beans look like this:
import java.io.Serializable;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.validation.constraints.NotNull;
import co.com.psl.connectnetwork.service.AuthenticationService;
import lombok.Data;
#Named
#SessionScoped
#Data
public class LoginBean implements Serializable {
}
My first issue, is that as I mentioned before, I wanted to introduce Spring, so I had in my application context xml file
<context:annotation-config />
<context:component-scan base-package="co.com.package" />
That was causing me problems because it seemed that Spring scanned my JSF managed beans , and treated them as Spring beans, which I don´t have any issue with that, but in practice those beans were singleton !!! , so terrible for an application which manages some state among logged users.
So I solved it by excluding JSF beans from spring container, I did it by introducing this:
<context:component-scan base-package="co.com.scannedpackage" >
<context:exclude-filter type="regex" expression="co.excludedpackage.*Bean" />
</context:component-scan>
So It did not seem to me so terrible , and as it seems to be some imcompatibility I though It was better that JSF beans will not be managed by Spring.
2nd Question: Do you agree?
As I said, I will have some #Service (Spring annotations) beans which I will eventually have to inject into the JSF managed beans . Initially I used #Inject to inject the service bean into the JSF bean , and it worked perfectly , the only issue is that when the JSF bean was using javax.enterprise.context.SessionScoped , it forced that all attributes are Serializable, so I made the #Service Spring bean implement the Serializable interface, which I dont think it is nice , even if it works, it seems to me a contradiction and a spring singleton bean (stateless) is forced to be serialized. So I tried to use the #Autowired anotation in the JSF managed bean , but the bean was not been injected and I got a null reference. Basically I guess the error I think it was, to use #Autowired in a bean which is not managed by spring.
3rd Question: How can I make it work ? I really think it is better to use #Autowired than to have spring beans serializable .If the ApplicationScope/viewScope/SessionScope JSF bean is passivated, will the Spring bean be injected again?, I don´t think so. If #ManagedBean is used, will it work ?
Another issue I am having, is that if my JSF beans are managed by CDI, It seems that javax.faces.bean.ViewScoped does not work well with CDI
4th Question: Is that so? Do you recommend me to use #ManagedBean instead of #Named? If I use #ManagedBean, how do I inject Spring dependencies? Is there any other CDI scope I could use instead of ViewScoped?
Now moving from JSF to Spring, I really want to use Spring in my applications, Features like Spring-Data, Spring-Security and others, the advantages of Spring singleton beans over EJB Stateless beans, are things I don´t want to miss. In my application, I will have a datasource created in the Java EE server or Java EE container. Then, I will bind that datasource internally in my application. So in my applicationContext.xml, I have:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<bean id="datasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/jndi-spring"/>
<property name="lookupOnStartup" value="true"/>
<property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>
<!-- <jee:jndi-lookup id="datasource" jndi-name="java:/ConnectNetworkDS"/> -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="persistenceUnitName" value="persistenceUnit2" />
<property name="packagesToScan" value="co.com.packagestoscan" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
<jpa:repositories base-package="co.com.packagewhererepositoriearelocated" />
</beans>
Please note that I am using Spring data and this line
<jpa:repositories base-package="co.com.packagewhererepositoriearelocated" />
is to indicate the interfaces annotated with #org.springframework.stereotype.Repository.Resository
Unfortunately, when I deploy my application, I get:
ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC000001: Failed to start service jboss.deployment.unit."deployedwar.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."deployedwar.war".WeldStartService: Failed to start service
So I was doing so internet research, and I included :
persistence.xml
CdiConfig class
The content of persistence.xml is:
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="persistenceUnit">
<class>co.com.entityClass1</class>
<class>co.com.entityClass2</class>
<jta-data-source>java:/jndi-string</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
</properties>
</persistence-unit>
</persistence>
And CdiConfig class:
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
public class CdiConfig {
#Produces
#Dependent
#PersistenceContext
private EntityManager entityManager;
}
5th Question: Can somebody please tell me why this is required ? Shouldn´t spring be able to inject the enntityManager into the #Repository Spring beans ? Why a persistence.xml is necessary ? Why does it seems that injection into #Repository Spring beans have to be done by Spring ? I think this somehow is redundant
Isn´t it recommendable to use old JSF annotations?
That's true. In JSF we're moving away from the JSF native beans and injection in favor of CDI. Although still not officially so, #ManagedBean and friends should be considered effectively deprecated.
#ViewScoped should work fine with CDI, but make sure you're importing the right one. The old one does not work, the newer one does. The one you need is:
javax.faces.view.ViewScoped
See CDI compatible #ViewScoped

How to reach other project's resources from spring applicationContext?

I have a project named fc-jsf. This project's spring context refers to an other spring context named Beans.xml in the fc-bus project. I have fc-bus as project dependency for fc-jsf.
I import the Beans.xml like this:
<import resource="classpath*:com/fc/spring/Beans.xml" />
Its working, but it says that the fc-jsf project can't see the properties declared in Beans.xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>com/fc/properties/database.properties</value>
</property>
</bean>
The exception is:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/com/fc/properties/database.properties]
How to reach the database.properties without copying the properties file to the fc-jsf project?
edit: theese are maven projects, database.properties is in fc-bus -> src/main/resurces/com/fc folder.
Try using the properties like
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:com/fc/properties/database.properties</value>
</property>
</bean>
otherwise it doesn't know which package it should use it from
Try with <value>classpath*:database.properties</value>

Has anyone tried datanucleus JPA implementation with orientdb?

I am trying to implement Datanucleus JPA for orientdb for my java project. I am able to successfully make it work with datanucleus3.1.2, mongodb. but when I tried to do with orientdb, I read it works with 2.x (i guess ONLY 2.x at moment). I replaced all datanucleus 3.x jars with 2.x.
For mongodb I have following works fine
Persistence.createEntityManagerFactory("mongodb");
with persistence.xml
<persistence-unit name="mongodb">
<properties>
<property name="datanucleus.ConnectionURL" value="mongodb:localhost:27017/db"/>
<property name="datanucleus.storeManagerType" value="mongodb" />
<property name="datanucleus.autoCreateSchema" value="true" />
</properties>
</persistence-unit>
Has anyone able to get it work? How to create entity manager factory for orientdb?
How the persistence.xml should look like?
I keep getting
javax.persistence.PersistenceException: No Persistence provider for EntityManager named orientdb
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:84)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)

PropertyPlaceholderConfigurer works from Maven command line, but not from Eclipse?

I have Eclipse configured to use an external maven instance. Nonetheless I have an integration test that runs fine from the command line, but fails from within Eclipse. The error is a class Spring application context bean error:
Cannot convert value of type [java.lang.String] to required type
The culprit it a bean that sets property values using a PropertyPlaceholderConfigurer.
<!-- property settings for non-JNDI database connections -->
<bean id="placeholderConfigUuid" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="location" value="classpath:database.properties" />
<property name="placeholderPrefix" value="$DS{" />
</bean>
I know which bean is failing because it appears in the stack trace and because when I replace the $DS{hibernate.dialect} with a static value it works.
EDIT: Here is where the property values are used:
<bean id="myTestLocalEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myapp-core" />
.......ommitted for brevity.......
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<!-- The following use the PropertyPlaceholderConfigurer but it doesn't work in Eclipse -->
<property name="database" value="$DS{hibernate.database}" />
<property name="databasePlatform" value="$DS{hibernate.dialect}" />
</bean>
</property>
</bean>
I have two questions:
1) Since M2Eclipse is using the same Maven setup as the command line, why does one work and the other fail?
2) How to fix this? I really like the ability to run a single jUnit test from within Eclipse on demand.
Does filtering work for a "regular" unit test under Eclipse?
Is m2eclipse configured to process resources and tests resources on resource changes:
alt text http://www.imagebanana.com/img/rwd919ek/screenshot_008.png
Is there anything particular to mention about your integration tests (from a Maven point of view)?
You are using M2Eclipse (up-to-date release?) you are using Maven 3 inside Eclipse, but i assume you are using Maven 2 (2.2.1?) on command line...On the other side you are saying that your "Integration test" is running on command line (build an environment etc.) but you would like to run "Unit Test" from within Eclipse...A Unit Test is different from an integration test...and i'm not astonished that you integration test does not work from Eclipse...May be we can say more if we see the POM's which are used and the code?

JBoss Microcontainer + AOP in a standalone app

I'm trying to create a standalone app using JBoss Microcontainer for IoC and JBoss AOP for, well, AOP.
I've boot-strapped, deployed a descriptor with AOP XML, so far so good.
But the aspect is not performed. Do I need to enable AOP plugin or something?
Note that I don't want to add a build step - I want it to work like Spring AOP.
Please check the code below.
Thanks for help.
<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd"
xmlns="urn:jboss:bean-deployer:2.0"
xmlns:aop="urn:jboss:aop-beans:1.0">
<bean name="myGarage" class="jbmctest.Garage">
<property name="car">
<bean name="myCar" class="jbmctest.Car">
<property name="name">Red Devil</property>
</bean>
</property>
</bean>
<aop:interceptor name="FuelInterceptor" class="jbmctest.FuelInterceptor"/>
<aop:bind pointcut="execution(* *->*(..)">
<aop:interceptor-ref name="FuelInterceptor"/>
</aop:bind>
</deployment>
You're missing the pieces that are in aop.xml in JBossAS5 -> conf/bootstrap/aop.xml.
I've eventually solved this, and wrote an article for those who will try the same.
http://ondra.zizka.cz/stranky/programovani/java/jboss-aop-howto-example-standalone-app.texy