Spring Beans getting initialised twice for Entity Manager - spring

I am having a bean defined as below
<bean id="batchManagementService" class="com.amdocs.dc.sprint.batch.service.BatchManagementServiceImpl" autowire-candidate="false">
<property name="repository" ref="batchPersistenceRepository" />
<property name="timeService" ref="batchTimeService" />
<property name="validator" ref="batchValidator" />
</bean>
I am refering this bean in two places in different modules.
However it is getting initialised with two differnt values.
with the JDK proxy which performs correct DB transactions
with the implementor class directly "BatchManagementServiceImpl" as mentioned above.
IN the second case the Entity manager is returning null causing all DB transactions to fail.
The implementor class contains transactional methods.
Any help on this will be appreciated..

Not quite clear from the description for me, but it sounds like your applicationContext is misconfigured within the modules.
Maybe you try an approach like:
MODULE_A:
-applicationContextA.xml
MODULE_B (which should use MODULE_A's beans )
-applicationContextB.xml
MODULE_C (which should use MODULE_B and MODULE_A )
-applicationContextC.xml
The WRONG approach is:
applicationContextA.xml:
<beans xmlns="http://www.springframework.org/schema/beans">
...
<bean id="batchManagementService"...>
applicationContextB.xml:
<beans xmlns="http://www.springframework.org/schema/beans">
<import resource="applicationContextA.xml"/>
<bean id=anotherBean...
applicationContextC.xml:
<beans xmlns="http://www.springframework.org/schema/beans">
<import resource="applicationContextB.xml"/>
<bean id=anotherBean...
In this case, when applicationContextC is created, batchManagementService will be instantiated twice.
Try this one:
applicationContextA.xml:
<beans xmlns="http://www.springframework.org/schema/beans">
...
<bean id="batchManagementService"...>
applicationContextB.xml:
<beans xmlns="http://www.springframework.org/schema/beans">
<!--No import here! -->
<!--<import resource="applicationContextA.xml"/>-->
<bean id=anotherBean...
applicationContextC.xml:
<beans xmlns="http://www.springframework.org/schema/beans">
<!-- No import here -->
<!--<import resource="applicationContextB.xml"/>-->
<bean id=anotherBean...
applicationContextFull.xml
<beans xmlns="http://www.springframework.org/schema/beans">
<import resource="applicationContextA.xml"/>
<import resource="applicationContextB.xml"/>
<import resource="applicationContextC.xml"/>
</beans>
, and try to boot application context using applicationContextFull.xml.
Hope this helps.

Related

deployerConfigContext.xml has no effect

I tried to get a CAS-server up and running using https://github.com/apereo/cas-overlay-template for a side project (I'm a student), but I have never used maven or spring before.
I'm trying to hook my own IPersonAttributeDao into the CAS-server. However, when I put my deployerConfigContext.xml under src/main/webapp/WEB-INF/, nothing actually changed when I repackaged (using the build script) and deployed to tomcat8. (Yes, I did restart tomcat).
Below the contents of my deployerConfigContent.xml 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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="credentialsToPrincipalResolvers">
<list>
<bean id="primaryPrincipalResolver"
class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository"/>
</bean>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository"/>
</bean>
<bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver">
<property name="attributeRepository" ref="attributeRepository"/>
</bean>
</list>
</property>
<property name="authenticationHandlers">
<list>
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
<property name="users">
<map>
<!-- Login stays the default casuser:Mellon, no idea why -->
<entry key="test" value="1234"/>
</map>
</property>
</bean>
<!-- DO NOT EVER PUT THIS BEAN IN PRODUCTION!!! -->
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler"/>
</list>
</property>
</bean>
<!-- <bean id="attributeRepository" class="class.i.am.trying.to.hook.in">
</bean>-->
<!-- This doesn't seem to work -->
<bean id="attributeRepository"
class="org.jasig.services.persondir.support.StubPersonAttributeDao">
<property name="backingMap">
<map>
<entry key="uid" value="uid" />
<entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
</map>
</property>
</bean>
</beans>
What am I missing?
UPDATE:
I reread the documentation (https://apereo.github.io/cas/5.0.x/), and found that deployerConfigContext.xml was supposed to be in resources, and not in webapp/WEB-INF as I found on the internet. I moved it, and now I'm finally getting errors in the log (which means the file is being read).
Error below:
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.jasig.cas.authentication.PolicyBasedAuthenticationManager] for bean with name 'authenticationManager' defined in class path resource [deployerConfigContext.xml]
I found a reference to PolicyBasedAuthenticationManager in the docs, but trying that gave the same error (with the other classname ofcourse).
Bean classes of enabled beans must be deployed in bean archives.
A library jar, EJB jar, application client jar or rar archive is a
bean archive if it has a file named beans.xml in the META-INF
directory. The WEB-INF/classes directory of a war is a bean archive if
there is a file named beans.xml in the WEB-INF directory of the war. A
directory in the JVM classpath is a bean archive if it has a file
named beans.xml in the META-INF directory.
One suggestion, if you are using Spring, you can also set #Annotation to define beans.

Spring 3.2 + Hibernate 4.2 : "The application must supply JDBC connections" - What is wrong with my configuration?

I'm struggling to understand how to properly configure Spring 3.2 and Hibernate 4.2. After working through several issues over the last few days, I ran into this exception while trying to execute a query in my DAO:
java.lang.UnsupportedOperationException: The application must supply JDBC connections
org.hibernate.service.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:62)
org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1426)
org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:59)
com.bsj.demo.rest.dao.DemoUserDaoImpl.getAllDemoUsers(DemoUserDaoImpl.java:41)
Here are my Spring and Hibernate files:
context.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:property-placeholder location="classpath:spring/data-access.properties"/>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/restdemo"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="persistenceUnitManager">
<bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<context:component-scan base-package="com.bsj.demo.rest.*">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:spring-configured />
<context:annotation-config />
<bean class="com.bsj.demo.rest.spring.config.AppConfig"/>
</beans>
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="RESTDemoJPA" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
</properties>
</persistence-unit>
What am I missing? My understanding is that with Spring defining the datasource and persistence unit, there should be very little configuration needed in the persistence.xml. Am I completely wrong here?
Server is Tomcat 7, dependencies managed by Maven. I understand this is a commonly asked question on SO, but after trying several solutions I have not found a way to resolve this problem.
Have a look over here. Might be it can resolve your issue.
https://github.com/abdulwaheed18/Spring-HIbernate-Integration/blob/master/src/beans.xml
Alright, I figured out the problem and it wasn't really related to configuration. The problem was how I was instantiating the EntityManager in my code.
In the configuration, I needed to add the following to the entityManager bean definition:
<property name="persistenceUnitName" value="RESTDemoJPA" />
The bigger problem was that I was creating the EntityManager in each DAO by getting an instance from the EntityManagerFactory. Instead, I should have been allowing Spring to inject it via the PersistenceContext annotation as follows:
#PersistenceContext(unitName="RESTDemoJPA")
private EntityManager em;
After doing that, I removed all calls to em.getTransaction(), annotated the class as #Transactional and the exceptions went away. After that, I could query the database.
TL;DR: Configuration was correct minus defining the Persistence Unit name in the entityManager definition. Changed EntityManager instantiation from manual to Spring injection.

How can I use Spring Batch Admin with Spring 3.2 and #Schedule annotation?

I integrated Spring Batch Admin into my app, which uses Spring 3.2.
Now I try to annotate a method with #Scheduled and activate this with <task:annotation-driven/>.
When I launch the webapp I get this exception:
Caused by: java.lang.IllegalStateException: #Scheduled method 'removeInactiveExecutions'
found on bean target class 'SimpleJobService', but not found in any interface(s) for bean
JDK proxy. Either pull the method up to an interface or switch to subclass (CGLIB) proxies
by setting proxy-target-class/proxyTargetClass attribute to 'true'
The SimpleJobService of Spring Batch Admin uses this annotation on a method.
In Spring 3.2. it seems, that there is no need to put cglib into the classpath and spring-asm is obsolete, too. I excluded the spring-asm dependency from spring-batch-integration.
Where can I set proxy-target-class=true (I already tried it on <tx:annotation-config> and <aop:config>?
How can I use #Scheduled in my application?
Add execution-context.xml in META-INF\spring\batch\override, set proxy of SimpleJobServiceFactoryBean to target class
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Original jobRepository missing read ${batch.isolationlevel} -->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" p:isolationLevelForCreate = "${batch.isolationlevel}"/>
<!-- Original jobService conflicted with #EnableScheduling -->
<bean id="jobService"
class="org.springframework.batch.admin.service.SimpleJobServiceFactoryBean">
<aop:scoped-proxy proxy-target-class="true" />
<property name="jobRepository" ref="jobRepository" />
<property name="jobLauncher" ref="jobLauncher" />
<property name="jobLocator" ref="jobRegistry" />
<property name="dataSource" ref="dataSource" />
<property name="jobExplorer" ref="jobExplorer" />
<property name="transactionManager" ref="transactionManager" />
</bean>
</beans>

Spring property reference is not working

<bean name="readerService" class="com.mayank.example1.ReaderService"/>
<property name="reader" ref="fileReader" />
</bean>
<bean name="fileReader" class="com.mayank.example1.FileReader">
<constructor-arg value="resources/myfile.txt" />
</bean>
Reder service take reader as argument in its constructor
Reader is Interface.
FileReader is class that implement Reader
In spring It is not taking property reader and throwing exception:
Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 15 in XML document from class path resource [reader-beans.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'property'. One of '{"http://www.springframework.org/schema/beans":import, "http://www.springframework.org/schema/beans":alias, "http://www.springframework.org/schema/beans":bean, WC[##other:"http://www.springframework.org/schema/beans"]}' is expected
It looks like you are closing the bean tag too early (note the /> at the end, shouldn't this be just >?):
<bean name="readerService" class="com.mayank.example1.ReaderService"/>
<property name="reader" ref="fileReader" />
</bean>
Make sure you have the required xml namespaces bean and context provided at the top of your configuration file. My example uses version 3.1 of Spring you may need to adjust for the version of Spring you are using.
Also notice the adjustment to the readerService bean tag which was being closed too early.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean name="readerService" class="com.mayank.example1.ReaderService">
<property name="reader" ref="fileReader" />
</bean>
<bean name="fileReader" class="com.mayank.example1.FileReader">
<constructor-arg value="resources/myfile.txt" />
</bean>
</beans>

Inject JAXBContext into spring

I am trying to inject a JAXBContext into spring application context, by:
<bean id="jaxbContext" class="javax.xml.bind.JAXBContext" factory-method="newInstance">
<constructor-arg type="java.lang.Class" value="com.package.MyClassName"/>
</bean>
It throws an exception:
No matching factory method found: factory method 'newInstance'
And I also try :
<bean id="jaxbContext" class="javax.xml.bind.JAXBContext" factory-method="newInstance">
<constructor-arg type="java.lang.String" value="com.package"/>
</bean>
And It throws an an exception:
javax.xml.bind.JAXBException: "com.package" doesnt contain ObjectFactory.class or jaxb.index
I did put a jaxb.index file inside the package "com.package" and has a single line "MyClassName" in the file.
#Tomasz's answer is the solution I'd recommend, but if you want to stick with JAXBContext, then the reason your first example failed is that the static getInstance() method on JAXBContext doesn't take a single Class argument, it takes a vararg list of them. So you need to inject a list, not a single class:
<bean id="jaxbContext" class="javax.xml.bind.JAXBContext" factory-method="newInstance">
<constructor-arg value-type="java.lang.Class">
<list>
<value>com.package.MyClassName</value>
</list>
</constructor-arg>
</bean>
Have you tried Spring OXM? The last line is important, namespaces are for reference only:
<?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:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd">
<oxm:jaxb2-marshaller id="marshaller" contextPath="com.package"/>
</beans>
See 8.4. XML Schema-based Configuration. Yu'll also need spring-oxm on your classpath.
this will resolve the problem for jaxb.index file or ObjectFactory problem in spring env. provide the value of the package where the classes are their which generate the xml
enter code here`
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="packagesToScan" >
<value>com.adarsh.spring.integration.entities</value>
</property>
</bean>`

Resources