JPA with Spring-security-ACL - spring

is it possible use JPA in spring security ACL, I can see only jdbc implementation.
here is my JPA setup in beans:
<beans:bean id="producerService" class="cz.services.RepositoryProducerService" />
<jpa:repositories base-package="cz.repository" />
<beans:bean id="myEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="cz.models" />
<beans:property name="jpaVendorAdapter">
<beans:bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</beans:property>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="myEmf" />
</beans:bean>
<beans:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url"
value="jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8" />
<beans:property name="username" value="root" />
<!--<property name="password" value="test" /> -->
<beans:property name="password" value="test1"></beans:property>
</beans:bean>
but I have a problem with Transaction manager, beacuse I use org.springframework.orm.jpa.JpaTransactionManager
instead of:
org.springframework.jdbc.datasource.DataSourceTransactionManager.
Main problem is when I start create acl, in first try I have exception transaction must be running, is second try (in broswer back and try it again) is it okay.
Here is error from first try:
java.lang.IllegalArgumentException: Transaction must be running
at org.springframework.util.Assert.isTrue(Assert.java:65)
at org.springframework.security.acls.jdbc.JdbcMutableAclService.createOrRetrieveSidPrimaryKey(JdbcMutableAclService.java:218)
at org.springframework.security.acls.jdbc.JdbcMutableAclService$1.setValues(JdbcMutableAclService.java:135)
at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:899)
at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:890)
can someone help me with this? Thanks

Problem solved! :)
I search that JPA transaction manager in spring
A snippet from Spring 3's JavaDoc:
This transaction manager also supports direct DataSource access within
a transaction (i.e. plain JDBC code working with the same DataSource).
This allows for mixing services which access JPA and services which
use plain JDBC (without being aware of JPA)!
but problem was in my cglib - I have to use
<tx:annotation-driven transaction-manager="transactionManager" />
and remove #Transactional from interface JPA repository.
I found solution here too : What transaction manager should I use for JBDC template When using JPA ?
hope someone help it.

Related

Spring and Hibernate Application with Websphere

I am facing problem in deploying my application to Websphere 8.5
I am trying to build an application with Hibernate 5, Spring 5 and WebSphere 8.5. I am not able to build sessionFactory Object in my project. Not sure where the problem is. Whether wrt to dependency or I did something wrong.
Here's how I am getting my session.
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/bdcp_01_ORA_XA"/>
</bean>
<!-- Hibernate Session Factory -->
<beans:bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<!-- Hibernate configuration -->
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
<!-- The packages that contain our Hibernate model classes -->
<beans:property name="packagesToScan">
<beans:list>
<beans:value>com.gssc.model</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<!-- Hibernate transaction management -->
<beans:bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
Getting error as Shown below:-
Error creating bean with name 'sessionFactory' defined in
ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Invocation
of init method failed; nested exception is
java.lang.NoSuchMethodError:
javax/persistence/Table.indexes()[Ljavax/persistence/Index;
Also if I change the version as mentioned above, which version shall i move ahead. And shall i create sessionFactory as mentioned.
Please help

Spring/Hibernate No session found for current thread (config)

I'm trying to understand the configuration for Spring and Hibernate together. Every time I make calls to the database, I get a no session found for current thread error in my console (doesn't stop the app since I just create a new session if it can't find one). I have a standard STS Maven setup. The below is how I have the configuration currently setup. However, if I take everything in the root-context.xml and put it at the bottom of servlet-context.xml, it works without any errors. So I'm guessing something within servlet-context.xml is "overwriting" something and not taking the #Transactional annotations I have on my service. But how do you config around that?
root-context.xml
<!-- Configure JDBC Connection-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url" value="jdbc:derby:C:\Users\Steven\Desktop\Programming\db-derby-10.10.1.1-bin\db-derby-10.10.1.1-bin\bin\mydb" />
</bean>
<!-- Configure Hibernate 4 Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="packagesToScan" value="com.css.genapp" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DerbyTenSevenDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
servlet-context.xml
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basenames">
<beans:list>
<beans:value>format</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<context:component-scan base-package="com.css.genapp" />
You must define component scan on both servlet-context.xml and root-context.xml
root-context.xml: for service, repository...
servlet-context.xml: for controller and web relate component.
Hope it can help. You can check detail on this sample Spring, JPA and hibernate integration
I think in your Hibernate configuration you configured <prop key="hibernate.current_session_context_class">thread</prop> Like this.
Remove the property because it really breaks proper session/transaction management in spring.
You have to import root-context.xml since only servlet-context.xml will be read by dispatcher servlet. Add the following line in your servlet-context.xml :

Could not fetch messages from Webpshere MQ sometimes even though the application and websphere mq is up and running

I have encountered a problem in fetching the messages from Websphere MQ.
We have a application running in spring TC server.
Application is using spring integrator JMS adaptor to receive the messages from Websphere MQ server.
Following is the spring configuration we used.
Problem we are facing is, sometime even though the websphere mq is up and running and application is up and running, the application is not able to fetch the messages so that messages are falling to websphere mq dead letter queue
Is there any possibility for the above scenario? We are not able to reproduce this scenario
<beans:bean id="connectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<beans:property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP" />
</beans:property>
<beans:property name="queueManager" value="queueManager" />
<beans:property name="hostName" value="hostName" />
<beans:property name="channel" value="channel" />
<beans:property name="port" value="port" />
<beans:property name="clientReconnectOptions">
<util:constant static-field="com.ibm.msg.client.wmq.WMQConstants.WMQ_CLIENT_RECONNECT"/>
</beans:property>
</beans:bean>
<beans:bean id="mqSeriesConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<beans:property name="username" value="username"/>
<beans:property name="password" value="password"/>
<beans:property name="targetConnectionFactory" ref="connectionFactory"/>
</beans:bean>
<beans:bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
<beans:property name="connectionFactory" ref="mqSeriesConnectionFactory" />
</beans:bean>
<beans:bean id="mqQueueG3Receive" class="com.ibm.mq.jms.MQQueue">
<beans:constructor-arg value="receivequeue" />
<beans:property name="targetClient" value="1"/>
</beans:bean>
<beans:bean id="mqQueueG3Send" class="com.ibm.mq.jms.MQQueue">
<beans:constructor-arg value="sendqueue" />
<beans:property name="targetClient" value="1"/>
</beans:bean>
<jms:message-driven-channel-adapter id="MessageManagerJmsAdapter"
connection-factory="mqSeriesConnectionFactory"
destination="mqQueueG3Send"
concurrent-consumers="7"
max-concurrent-consumers="40"
transaction-manager="jmsTransactionManager"
message-converter="resultMessageConverter"
channel="MessageManagerIncomingChannel" />
<channel id="g3MessageManagerIncomingChannel" />
<service-activator id="MessageManagerActivator"
input-channel="MessageManagerIncomingChannel"
ref="MessageManager"
method="manageMessage" />
Thanks
WebSphere MQ is a little finicky when it comes to Spring Integration JMS. instead of building up the message-driven-channel-adapter with connection settings, you may want to try configuring your own DefaultMessageListenerContainer and using that. things to look out for include;
sessionTransacted = true
transactionManager = [ref]
so this would look like;
<int-jms:message-driven-channel-adapter channel="myChannel" container="myContainer"/>
<bean id="myContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="myConnectionFactory"/>
<property name="destination" ref="myQueue"/>
<property name="sessionTransacted" value="true"/>
<property name="transactionManager" ref="myTransactionManager"/>
</bean>
If they are going to the DLQ it means delivery failed, not that the app could not "fetch the message". I would expect there to be an error logged.
Another thing to look for is if the container's threads (7) are blocked somewhere in your MessageManager bean. Take a thread dump (jstack or visualVM) to find out what the container threads are doing.
Finally, trace logging will show the container thread activity when idle.

Setup Connection Pooling in Spring MVC

How can I setup connection pooling in Spring MVC? I am working on an intranet website powered by Spring MVC 2.5 and jQuery. This is my first attempt at web development.
I am not sure but, I am only using this in my spring configuration file and I saw this in the Spring MVC step By Step tutorial
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
This looks good during development and connection speed is fast but I am not sure if this will still holds true if many users are concurrently connected.
How can I achieve this? I have read that this is not an optimal connection datasource.
You might want to look at c3p0, which has some powerful configuration and optimization available.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="..." />
<property name="jdbcUrl" value="..." />
<property name="user" value="..." />
<property name="password" value="..." />
</bean>
Your current setup is correct, all you need to do in order to use basic connection pooling is use a DataSource implementation provided by a connection pooling library, in your case Apache DBCP. See this post for a few links to other alternatives, C3P0 being one of them.
Note that when you actually use the DataSource bean you're injecting wrap it in a SimpleJdbcTemplate or use DataSourceUtils to obtain a Connection - see Spring JDBC Documentation
For connection Pooling
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
//Add this two more parameters
<property name="**initialSize**" value="20" />
<property name="**maxActive**" value="30" />
</bean>
connection pool will create 20 database connection as initialSize is 20 and goes up to 30 Database connection if required as maxActive is 30.

Spring/JTA/JPA DAO integration test doesn't rollback?

My DAO integration tests are failing because entities created during the tests are still in the database at the start of the next test. The exact same behavior is seen from both MySQL 5 and H2.
The test classes are annotated with:
#Transactional
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration( { "/testPersist-applicationContext.xml" })
The transaction bean configuration in the test application context is as follows:
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
</bean>
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
The entity manager is configured as follows:
<bean id="myappTestLocalEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myapp" />
<property name="persistenceUnitPostProcessors">
<bean class="com.myapp.core.persist.util.JtaPersistenceUnitPostProcessor">
<property name="jtaDataSource" ref="myappPersistTestJdbcDataSource" />
</bean>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="database" value="$DS{hibernate.database}" />
<property name="databasePlatform" value="$DS{hibernate.dialect}" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
</prop>
<prop key="hibernate.format_sql">true"</prop>
<prop key="hibernate.use_sql_comments">true</prop>
</props>
</property>
</bean>
<context:annotation-config />
Everything in the log files seem to be fine...I can see messages from Spring about rollback and from Atomikos about rollback as well. But frankly, the logs are so huge and so complex, I could easily be missing something...
Yet the inserted test data remains! Any clues?
It turned out that my C3P0 JDBC data source was not XA aware and was therefore not participating in the transaction. Why I did not get an error, nor a warning in the log file, I do not know. Nonetheless, the reason you cannot use an XA aware data source is explained very nicely here. Note that the data source does not need to be XA capable...just XA aware.
Replacing the C3P0 data source with the following one solved the problem.
<bean id="myappJTANonXADataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean">
<property name="uniqueResourceName" value="myappDatabase" />
<property name="driverClassName" value="$DS{hibernate.connection.driver_class}" />
<property name="url" value="$DS{hibernate.connection.url}" />
<property name="user" value="$DS{hibernate.connection.username}" />
<property name="password" value="$DS{hibernate.connection.password}" />
<property name="maxPoolSize" value="20" />
<property name="reapTimeout" value="300" />
</bean>
I think you will need to go through the logs in details. It could be that the rollbacks you are seeing are working, except that something else has executed a commit first. I also cannot see anything in your code which indicates automated rollback. And that it should occur at the end of each test. If you are depending on a timeout based rollback it could be that the second test is running before the timeout occurs, therefore it sees the data before it is rolled back.
Many options here there is :-)

Resources