Issues while running JUnit on maven project using Spring JTA - spring

I have a Spring + Hibernate project deployed on JBoss 5. It was using Ant earlier and recently I have modified the project structure to use Maven 2. But all the code and config files are the same.
I am using Spring JTA for transaction management in my project. I am able to perfecly buid the project and deploy it on JBoss. But when I try to execute the JUnit tests it gives me the following error:
java.lang.IllegalStateException: No JTA UserTransaction available - specify either 'userTransaction' or 'userTransactionName' or 'transactionManager' or 'transactionManagerName'
at org.springframework.transaction.jta.JtaTransactionManager.checkUserTransactionAndTransactionManager(JtaTransactionManager.java:473)
at org.springframework.transaction.jta.JtaTransactionManager.afterPropertiesSet(JtaTransactionManager.java:413)
The wierd thing is that this was working perfeclty fine when I was using Ant. It started coming after the migration to maven.
This is the entry in spring-jpa-conf.xml file:
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
</bean>
And this is the Junit code:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:spring-conf.xml" })
#Transactional(value = "transactionManager")
public abstract class LocalUsersTestBase {
#PersistenceContext(unitName="books-lemf")
protected EntityManager entityManager;
protected void getUsersDetails(List<Users> out) {
..........
}
I also tried to add a property in the config file entry as shown here:
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
<property name="userTransactionName" value="java:/TransactionManager"></property>
</bean>
But it gives the error:
Caused by: org.springframework.transaction.TransactionSystemException: JTA UserTransaction is not available at JNDI location [java:/TransactionManager]; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at org.springframework.transaction.jta.JtaTransactionManager.lookupUserTransaction(JtaTransactionManager.java:548)
at org.springframework.transaction.jta.JtaTransactionManager.initUserTransactionAndTransactionManager(JtaTransactionManager.java:425)
at org.springframework.transaction.jta.JtaTransactionManager.afterPropertiesSet(JtaTransactionManager.java:412)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1460)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1400)
... 37 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
Please help.
Thanks!!
This is my complete spring config file:
<?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:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
</bean>
<jee:jndi-lookup id="books-pu"
jndi-name="java:/books-emf"
cache="true"
lookup-on-startup="false"
proxy-interface="javax.persistence.EntityManagerFactory"
/>
<jee:jndi-lookup id="booksDataSource" jndi-name="java:/books-ds"/>
</beans>

Firsty, from spring reference documentation
If you use JTA in a Java EE container then you use a container
DataSource
, obtained through JNDI,
in conjunction with Spring’s
JtaTransactionManager
. This is what the JTA and JNDI lookup version
would look like:
The
JtaTransactionManager
does not need to know about the
DataSource
, or any other specific
resources, because it uses the container’s global transaction management infrastructure
then when you run the tests you need to a environment container managed to get a JTA User Transaction. In addition can you share with us the complete spring configuration

Related

org.hibernate.HibernateException: getNamedQuery is not valid without active transaction

I got an exception:
org.hibernate.HibernateException: getNamedQuery is not valid without active transaction org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:340)
$Proxy10.getNamedQuery(Unknown Source)
Here is my configuration:
...
<context:annotation-driven/>
<beans:bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
...
Also, I added context:annotation-driven since the tr:annotation-driven is not working, does <tx:annotation-driven/> use the transactionManager which obtain its own session from Hibernate?
I used my derived sessionFactory using Hibernate3 inside the annotated transaction, so how do I configure the Spring to do so?
The transaction manager has a dependency on session factory which it's using to manage transactions.
By adding <tx:annotation-driven /> you tell Spring how transactions are demarcated. In this case you can use annotations.
See the docs page how to use XML Schema-based configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean definitions here -->
</beans>

H2 + openJPA + JPA + Spring + apache Camel Java DSL configuration in intellij

I am using IntelliJ IDEA. I have created an embedded H2 database and defined a table in it. My module has the JPA framework support applied. There is no spring.config xml used. I want to do the following - create a persistent H2 database on filesystem and make jpa camel component read from the database.
The persistence.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="camel" transaction-type="RESOURCE_LOCAL">
<provider>
org.apache.openjpa.persistence.PersistenceProviderImpl
</provider>
<class>com.workflow2015.database.model.UserEntity</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:h2:./dtbase/MYDB;AUTO_SERVER=TRUE;"/>
<property name="openjpa.ConnectionDriverName" value="org.h2.Driver"/>
<property name="openjpa.Log" value="DefaultLevel=WARN, Tool=WARN, SQL=WARN, Runtime=WARN"/>
<property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
<property name="openjpa.ConnectionUserName" value="sa"/>
<property name="openjpa.ConnectionPassword" value=""/>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema" />
</properties>
</persistence-unit>
My camel context gets injected with spring-boot, and I am able to run other camel components and EIP. The result that I want to achieve is the following:
from("jpa://UserEntity?consumer.query=select o from UserEntity o")
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
//do smthing with it
}
});
I have UserEntity autogenerated from my DB schema into POJO. I am using maven for dependencies and the pom file has all the required dependencies.
The issue:
When I run the application for some reason it creates another database("testdb") with unknown schema to me and does not use the information provided in the persistence.xml
2015-06-05 22:35:00,980 [main ] INFO EmbeddedDatabaseFactory Creating embedded database 'testdb'
2015-06-05 22:35:02,138 [main ] INFO tainerEntityManagerFactoryBean - Building JPA container EntityManagerFactory for persistence unit 'default'
Why is EmbeddedDatabaseFactory creating this phantom database instead of using the one that I have created?
Consequently I cannot use the entity that I have created and error is shown that it cannot find schema.

unable to reference Spring services in JUnit

i am running a Karaf container with a number of beans implementing the com.mycompany.foo.IMyBean interface. i refer to them as "child beans". each such "child" bean is registered as a service. i also have a single "parent" bean that rounds up all those "child" services by using osgi:list. everything works just fine in runtime. however, when i run a very simple JUnit scenario, i get the following exception:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'BeanRefsList': Invocation of init method
failed; nested exception is java.lang.IllegalArgumentException:
Required 'bundleContext' property was not set.
this is the context.xml in my JUnit project:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
">
<bean id="ChildBean"
class="com.mycompany.foo.ChildBean">
</bean>
<osgi:service id="ChildBeanService" ref="ChildBean" interface="com.mycompany.foo.IMyBean"/>
<osgi:list id="BeanRefsList" interface="com.mycompany.foo.IMyBean"/>
<bean id="ParentBean" class="com.mycompany.foo.ParentBean">
<property name="childBeans" ref="BeanRefsList"/>
</bean>
</beans>
the test class also contains the following annotation entries:
#org.junit.runner.RunWith(SpringJUnit4ClassRunner.class)
#org.springframework.test.context.ContextConfiguration("context.xml")
please let me know what i am doing wrong. thank you for your time!
The error message explains it pretty clearly. The line that says
<osgi:list id="BeanRefsList" interface="com.mycompany.foo.IMyBean"/>
Needs too look more like
<bean id="ParentBean" class="com.mycompany.foo.ParentBean">
<property name="childBeans" ref="BeanRefsList"/>
</bean>
Where the property "bundleContext" gets set properly. I'm not familiar with OSGI, so I don't know what class/object needs to be set here. But, that's what's missing.
I'm not sure what OSGI is looking for that's making it tell you "bundleContext" property is missing, but it sounds like both osgi:list and osgi:service use some kind of bundleContext property.
Have you specified all of the same imported schemas in jUnit that you did for your runtime context?

Overriding System property in Spring PropertyPlaceHolderConfigurer for integration testing

I'm using a System property to define the location for an environment-specific properties file. However, I would like to override that value to something different for integration tests.
Here's my production spring setup. I'm using a custom PropertyPlaceholderConfigurer to resolve some encrypted property file values, but that's not important here:
<-- Spring configuration in file service-spring-beans.xml -->
<bean class="com.mycompany.MyPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:properties/${MY_ENVIRONMENT}/${MY_ENVIRONMENT}.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="false"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
At runtime, we define the value of MY_ENVIRONMENT as a Java system property. This all works as expected. However, for integration tests, I would like to define MY_ENVIRONMENT as "inttest", so the integration-test specific property file properties/inttest/inttest.properties is loaded.
I've tried to use a spring context loaded by the integration-test to set up a String bean with the id MY_ENVIRONMENT:
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="com.mycompany.myclasses"/>
<bean class="java.lang.String" id="MY_ENVIRONMENT">
<constructor-arg value="inttest"/>
</bean>
<!-- this imports the production spring context -->
<import resource="classpath:service-spring-beans.xml"/>
</beans>
However, the value of MY_ENVIRONMENT is not resolved , and I get this error when running the integration tests.
Caused by:
org.springframework.beans.factory.BeanInitializationException: Could
not load properties; nested exception is
java.io.FileNotFoundException: class path resource
[properties/${MY_ENVIRONMENT}/${MY_ENVIRONMENT}.properties] cannot
be opened because it does not exist
How can I override MY_ENVIRONMENT at inttest time without passing a System property to the JVM?
Since I was using the maven surefire plugin to run integration tests, the simplest solution turned out to be setting the system property using the surefire plugin configuration, like this:
<configuration>
<systemPropertyVariables>
<MY_ENVIRONMENT>inttest</MY_ENVIRONMENT>
</systemPropertyVariables>
<!-- ... -->
<configuration>
Since you don't want to use profiles, you can create multiple contexts and just include the proper context files for what you want. So for integration testing you have have your application-context.xml and an integration-property-context.xml file while, in the prod environment you would include the application-context.xml with a production-property-context.xml file. I've seen this approach used heavily to switch datasources between dev and prod where dev would be a BasicDataSource implementation and the prod environment references a JDNI DataSource.
This approach will help you avoid ActiveProfiles, but you run in to the problem of managing duplicate beans possibly which ActiveProfiles really simplified down.
you could look at overriding your whole property placeholder implementation using active profiles. that is, the default (no profile) launches your property placeholder, but a test profile (e.g. 'test') could create a new test bean for the property placeholder.
one of the challenges with property placeholder is that its loaded at the very early stages of the application context startup, so a normal override bean may not work.

Weird behaviour of import tag in spring's configuration file

I am working on the spring spring-3.2.2. I have created two java projects in eclipse.
SpringTest
Testclasspath
SpringTest project is having the below beans.xml in which the one bean is defined.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloWorld" class="com.spring.HelloWorld" init-method="testUpdate" scope="prototype">
<property name="message" value="Hello World!"/>
</bean>
</beans>
I have created the jar springtest.jar of the project SpringTest and it is been added in the classpath of the project Testclasspath. Bean configuration file for the Testclasspath project is talentacquisition.xml and it is importing the beans.xml file of the Springtest project. Please find the below content of talentacquisition.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="Beans.xml"/>
<bean id="juggler" class="com.springaction.springidol.Juggler" />
</beans>
I am confused with behavior of the import tag in the talentacquisition.xml How it is able to locate the Beans.xml which is present in the jar (springtest.jar) in the classpath and able to load the beans? Why spring is not giving any error ? Don't I have to modify the import tag in the talentacqusition.xml to following
<import resource="classpath:Beans.xml"/>
If import is able to locate the file Beans.xml , then when should we use classpath: and classpath* :?
ResourceLoaders are responsible for how Spring loads the resource. From the reference manual
The location path or paths supplied to an ApplicationContext
constructor are actually resource strings, and in simple form are
treated appropriately to the specific context implementation.
ClassPathXmlApplicationContext treats a simple location path as a
classpath location. You can also use location paths (resource strings)
with special prefixes to force loading of definitions from the
classpath or a URL, regardless of the actual context type.
The ClassPathXmlApplicationContext you're instantiating "treats a simple location path as a classpath location", i.e. it treats "Beans.xml" as "classpath:Beans.xml". Similarly, FileSystemXmlApplicationContext would treat "Beans.xml" as "file:Beans.xml".
Section 6.7 of the manual has more details too.

Resources