I'm new to WebSphere and am trying to host a simple website that I can log into using an Oracle database.
I can get to my website, but when I try and log in I get the following warning and am not able to log in:
[WARNING ] Detected JSESSIONID with invalid length; expected length of 23, found 28, setting: 99D3CCB2FF585D3B3E80293BFA1C to null.
[WARNING ] HHH000183: no persistent classes found for query class: select a FROM com.model.User a where username = 'user'
No entity found for query
The warning no persistent classes found for query class: is being thrown when I try and create the query to log in inside of my CommonServiceImple.java:
Query query = getEntityManager().createQuery("select a FROM " + className + " a where username = '" + username + "'");
The No entity found for query is caused in the next line trying to run the query. This is because the query object is null because of the previous warning: Object obj = query.getSingleResult();.
server.xml
<dataSource id="jdbc/test" jndiName="jdbc/test" type="javax.sql.DataSource">
<jdbcDriver id="oracle-driver" libraryRef="oracle-lib">
<library></library>
</jdbcDriver>
<connectionManager id="ConnectionManager" minPoolSize="1" numConnectionsPerThreadLocal="10"/>
<properties.oracle URL="jdbc:oracle:thin:#crappie.ddvc.local:1521:STILOG" password="password" user="user"/>
</dataSource>
<library id="oracle-lib">
<fileset dir="C:/Users/user/workspace/WebAdmin/WebContent/WEB-INF/lib/" includes="ojdbc6.jar"/>
</library>
web.xml
<resource-ref>
<description>DataSource</description>
<res-ref-name>jdbc/test</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
<mapped-name>jdbc/test</mapped-name>
</resource-ref>
ibm-web-bnd.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd"
version="1.0">
<virtual-host name="default_host" />
<resource-ref name="jdbc/test" binding-name="jdbc/test"/>
</web-bnd>
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_1_0.xsd"
version="1.0">
<persistence-unit name="pu1">
</persistence-unit>
</persistence>
applicationContext.xml
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="commonService" class="com.service.CommonServiceImpl"/>
<bean id="mainMenuService" class="com.service.MainMenuServiceImpl"/>
<bean id="storeFilterService" class="com.service.StoreFilterServiceImpl"/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="persistenceUnitManager" ref="pum"/>
<property name="persistenceUnitName" value="pu1" />
<property name="jpaProperties">
<props>
<prop key="org.hibernate.envers.store_data_at_delete">true</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jdbc/test</value>
</property>
<property name="cache"
value="true"/>
<property name="lookupOnStartup"
value="true"/>
<property name="resourceRef"
value="true"/>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="pum"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath:META-INF/persistence.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="dataSource"></property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="loginAction" scope="prototype" class="com.action.LoginAction">
<constructor-arg ref="commonService" />
</bean>
<bean id="userAction" scope="prototype" class="com.action.UserAction">
<constructor-arg ref="commonService" />
</bean>
</beans>
Nothing interesting in User.java
#Entity
#Table(name="WEB_PAGE_USERS")
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO, generator="seq")
#SequenceGenerator(name="seq", sequenceName="WEB_PAGE_USERS_ID_SEQ")
private Integer id;
private String username;
private String password;
private String name;
//...
}
Or the ComonServiceImpl.java
#Transactional
public class CommonServiceImpl implements CommonService{
private EntityManager em;
#PersistenceContext(unitName="pu1")
public void setEntityManager(EntityManager em) {
this.em = em;
}
// MTD added for explicit order by
#SuppressWarnings("unchecked")
public List<Object> findAll(String name) {
getEntityManager().clear();
String sql = "select a FROM " + name + " a";
Query query = getEntityManager().createQuery(sql);
return query.getResultList();
}
//...(other sql selects, updates, inserts)
}
LoginAction.java
public class LoginAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private CommonService service;
private String username;
private String password;
private String environment;
public LoginAction(CommonService service) {
this.service = service;
}
public String execute() throws Exception {
return Action.SUCCESS;
}
#SuppressWarnings({ "unchecked", "static-access" })
public String login() throws Exception {
//Encrypt input password
CEncrypt cEncrypt = new CEncrypt();
String encryptedPwd = cEncrypt.encryptString(password);
//Get user by Username
User user = (User) service.findUser(username, User.class.getName());
//Check if input password is the same as the password in the database & login
if (user!=null && user.getPassword().equals(encryptedPwd)) {
#SuppressWarnings("rawtypes")
Map session = ActionContext.getContext().getSession();
session.put("logged-in","true");
session.put("loggedIn", "true");
session.put("WebAdminUserID", user.getUsername());
session.put("WebAdminUsername", user.getName());
session.put("WebAdminID", user.getRole_id());
return Action.SUCCESS;
} else {
return Action.ERROR;
}
}
//...
}
UPDATE
I was able to test my connection to the datasource by manually calling the lookup. But since my website is built on the persistence unit I would like to fix that error instead of re-writing the project to call the connection directly like this:
public String getEnvironment() {
try
{
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource test = (DataSource)envCtx.lookup("jdbc/test");
Connection con = test.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from WEB_PAGE_USERS where username = 'user'");
while(rs.next()){
System.out.println("username="+rs.getString("username")+", password="+rs.getString("password")+", role id="+rs.getString("role_id"));
}
// environment = "[" + (String)envCtx.lookup("Environment") + "]";
} catch (Exception e)
{
System.out.println("Environment Exception: " + e.getMessage());
}
return environment;
}
Which does return the correct data username=user, password=password, role id=1
To fix my answer I had to add every model class I had with the #Entity annotation to my persistence.xml file. It seems that even though I am using an entityManager I still needed to specify all of the #Entity classes (normally in Tomcat the entityManager would automatically find all of the classes).
Also I was getting that [WARNING ] Detected JSESSIONID with invalid length; expected length of 23, found 28, setting: 99D3CCB2FF585D3B3E80293BFA1C to null. warning which was causing my session to be cleared each time a page loaded (makes it hard to stay logged in). So I increased the length to 28 in the server.xml on WebSphere.
server.xml
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>jsp-2.2</feature>
<feature>jndi-1.0</feature>
<feature>jdbc-4.0</feature>
<feature>localConnector-1.0</feature>
<feature>servlet-3.0</feature>
<feature>jaxrs-1.1</feature>
</featureManager>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint host="localhost" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
<dataSource id="jdbc/test" jndiName="jdbc/test" type="javax.sql.DataSource">
<jdbcDriver id="oracle-driver" libraryRef="oracle-lib"/>
<connectionManager id="ConnectionManager" minPoolSize="1" numConnectionsPerThreadLocal="10"/>
<properties.oracle URL="jdbc:oracle:thin:#crappie.local:1521:STILOG" password="password" user="user"/>
</dataSource>
<library id="oracle-lib">
<fileset dir="C:/Users/user/workspace/WebAdmin/WebContent/WEB-INF/lib/" includes="ojdbc6.jar"/>
</library>
<applicationMonitor updateTrigger="mbean"/>
<webApplication id="WebAdmin" location="WebAdmin.war" name="WebAdmin"/>
<httpSession idLength="28"></httpSession>
</server>
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_1_0.xsd"
version="1.0">
<persistence-unit name="pu1">
<class>com.model.App</class>
<class>com.model.AudioType</class>
<class>com.model.AuditRevisionEntity</class>
<class>com.model.ClosedGroup</class>
<class>com.model.ClosedSchedule</class>
<class>com.model.ClosedScheduleGroup</class>
<class>com.model.Department</class>
<class>com.model.Dnis</class>
<class>com.model.DnisVoiceTalent</class>
<class>com.model.GlobalXferGroupTemplate</class>
<class>com.model.Language</class>
<class>com.model.Location</class>
<class>com.model.MainMenu</class>
<class>com.model.NameValue</class>
<class>com.model.NameValueFunction</class>
<class>com.model.NameValueType</class>
<class>com.model.Peg</class>
<class>com.model.PegType</class>
<class>com.model.PharmacyConfig</class>
<class>com.model.Promo</class>
<class>com.model.PromoMessage</class>
<class>com.model.PromoSchedule</class>
<class>com.model.PromoType</class>
<class>com.model.Role</class>
<class>com.model.Schedule</class>
<class>com.model.ScheduleHours</class>
<class>com.model.ScheduleRecording</class>
<class>com.model.ScheduleType</class>
<class>com.model.Server</class>
<class>com.model.SpecialSchedule</class>
<class>com.model.SpecialScheduleRecording</class>
<class>com.model.Store</class>
<class>com.model.StoreAudio</class>
<class>com.model.StoreClosedGroup</class>
<class>com.model.StoreDepartment</class>
<class>com.model.StorePromo</class>
<class>com.model.StoreSchedule</class>
<class>com.model.StoreSpcSchedule</class>
<class>com.model.StoreType</class>
<class>com.model.StoreXferGroup</class>
<class>com.model.SystemMaintenance</class>
<class>com.model.TargetSystem</class>
<class>com.model.Timezone</class>
<class>com.model.Title</class>
<class>com.model.User</class>
<class>com.model.UserWebPage</class>
<class>com.model.UserWebPageAccess</class>
<class>com.model.UserWebPageClassType</class>
<class>com.model.VoiceTalent</class>
</persistence-unit>
</persistence>
Related
I am developing backend server with Java using spring 3.14 and hibernate 3.6.10 (and of course a lot of other libraries, but I suppose those are most important in that case). Server is used by several clients, one of them is android and due to mistake in android code (unnecessary multiple calls to backend one after another) I detected bug in my server which I can't solve wasting time for few days so far. So the problem is that when I run multiple DB queries (named queries to be exact) I got an error. What is really interesting the error varies! One time I get NPE on hibernate call "close connection" (stack trace 1), another I get "statement has been closed no further information" - stack 2. I saw few more, but all seemed to appear because statement had been released. To let You understand what I am doing to obtain the result I paste a code at the very bottom. Please also find pastes of my configuration below the stack traces.
Stack trace 1 - http://pastebin.com/4CABYAYH
Stack trace 2 - http://pastebin.com/PZ1R9Xxb
So to recap. Application fails when there are many connections to DB made asynchronously. After almost two days of thinking and trying I give up. Maybe somebody would help me, I will be grateful...
Anyway of course here comes all configuration and piece of code.
applicationContext:
<?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">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/testSchema"
p:username="train_together" p:password="..." p:initialSize="5" p:maxActive="10">
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<map>
<entry key="hibernate.hbm2ddl.auto" value="validate" />
<entry key="hibernate.enable_lazy_load_no_trans" value="true" />
<entry key="hibernate.connection.release_mode" value="after_transaction" />
</map>
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:component-scan base-package="com.train"/>
<context:spring-configured />
<context:annotation-config />
<tx:annotation-driven />
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_1_0.xsd"
version="1.0">
<persistence-unit name="JpaPersistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate" value="thread" />
</properties>
</persistence-unit>
</persistence>
As I said problem appears with multiple queries run in the same time so I simply created new REST endpoint which runs two threads with very simple named query.
here is my rest method:
#GET
#Path("1")
public Response test1(#QueryParam("i") #DefaultValue("10") int iterations) {
String key = UUID.randomUUID().toString().substring(0, 4);
System.out.println("*************************");
System.out.println(" request consumed: " + key);
System.out.println("*************************");
Thread t1 = new Thread(new Runnable() {
#Override public void run() {
try {
for (int i = 0; i < iterations; i++) {
System.out.println("*************************");
System.out.println("\tThread: 1 " + key + " iteration: " + (i+1));
userDao.getUsersOfTypeFromSportClub(UserType.CONTENDER, 1L);
}
} catch (Throwable e) {
System.out.println(Throwables.getStackTraceAsString(e));
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override public void run() {
try {
for (int i=0; i< iterations; i++) {
System.out.println("*************************");
System.out.println("\tThread: 2 " + key + " iteration: " + (i+1));
userDao.getUsersOfTypeFromSportClub(UserType.CONTENDER, 1L);
}
} catch (Throwable e) {
System.out.println(Throwables.getStackTraceAsString(e));
}
}
});
t1.start();
t2.start();
return Response.ok().build();
}
The UserDAO ovverides the base dao:
public abstract class BaseDao<T> {
protected EntityManager em;
protected EntityManagerFactory emf;
#PersistenceUnit
public void setEmf(EntityManagerFactory emf) {
this.emf = emf;
this.em = emf.createEntityManager();
}
}
P.S. the named query called by UserDao in my tests works properly.
I'm working on a project using Struts, Spring and Hibernate. After clicking on a button, the Struts action leads me through a DS and DAO, in which I try to call a native query to update the DB. Here is the error trace:
javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:618)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:310)
at $Proxy496.executeUpdate(Unknown Source)
at com.my.project.MyDAO.unsubscribe(MyDAO.java:307)
at com.my.project.MyDS.unsubscribe(MyDS.java:507)
at com.my.project.MyDS.updateValue(MyDS.java:784)
at com.my.project.MyAction.handleUpdate(MyAction.java:235)
MyDAO :
public class MyDAO extends
AbstractDAOGenericImpl<MyEntity> {
/** Entity Manager */
#PersistenceContext(unitName = "myPersistenceUnit")
private EntityManager entityManager;
#Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
public int unsubscribe(String entityId) throws JrafDaoException {
StringBuilder strQuery = new StringBuilder();
strQuery.append("update MYENTITY set SUBSCRIBE=:subscribe where ENTITY_ID=:entity_id");
final Query myQuery = getEntityManager().createNativeQuery(strQuery.toString(), MyEntity.class);
myQuery.setParameter("subscribe", "N");
myQuery.setParameter("entity_id", entityId);
try {
return myQuery.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
In MyDS :
#Autowired
#Qualifier("MyDAO")
private MyDAO myDao;
#Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
public int unsubscribe(String entityId) throws JrafDomainException {
return myDao.unsubscribe(entityId);
}
MyAction :
public class MyAction extends DispatchAction {
private MyDS myDS;
// ...
private ActionForward handleUpdate(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
MyForm myForm = (MyForm) form;
myDS.unsubscribe(myForm.getEntityId());
}
}
And application-context-spring.xml :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
<!-- Enterprise layer's dependencies -->
<bean id="springLocator"
class="com.jraf.bootstrap.locator.SpringLocator">
</bean>
<!-- To precise the persistence configuration name file -->
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>/META-INF/persistence-web.xml</value>
</list>
</property>
</bean>
<!-- EntityManagerFactory definition : JPA one -->
<bean id="myEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager"
ref="persistenceUnitManager" />
<property name="persistenceUnitName" value="myPersistenceUnit" />
</bean>
<!-- TransactionManager JPA one -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf" />
</bean>
<!-- EntityManagerFactory definition : JPA one -->
<bean id="myEmf2" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceUnitName" value="myPersistenceUnit2" />
</bean>
<!-- Transaction Manager definition : JPA one-->
<bean id="myTxManager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf2" />
</bean>
<!-- Enable annotation usage for transaction -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1" />
<property name="maxPoolSize" value="1" />
<property name="queueCapacity" value="1" />
</bean>
<bean id="myDS" class="com.my.internal.MyDS">
<property name="myDao" ref="MyDAO"/>
</bean>
<!-- Enable the annotation usage (bean injection for instance) -->
<context:annotation-config />
</beans>
I'm working on an existing project which is why the unsubscribe function already exists and uses a native query instead of a HQL one. But maybe I should use it instead...?
Thanks for your help.
I also faced the similar issue.
Adding
tx:annotation-driven transaction-manager="transactionManager"
to your spring context xml will resolve the issue.
Im unable to get a rollback working in my spring (3.0.5) jdbc application, running on Oracle 11.2
When I throw NoClassesException in the Controller below the row inserted by updatedB() remains in the dB.
I think this is because autoCommit is on (by default) in my dataSource so the commit has already happened and the rollback obviously doesn't work,
but I thought the Spring DataSourceTransactionManager handled all this and enforced the rollback?
Interestingly, when i turn autoCommit off in my dataSource ie comment in the :
"defaultAutoCommit" value="false"
and call the commit explicity myself ie comment in:
this.jdbcTemplate.getDataSource().getConnection().commit();
nothing happens ie the row is not commited at all,so it looks like i've done something stupid.
If someone could please point out this mistake I would be very gratefull
My code is :
public static void main(String[] args) {
String [] configList ={"database.xml","spring.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configList);
cont = (Controller)ctx.getBean("controller");
cont.transactionTest();
}
// Controller , called from Main()
public class Controller {
private JdbcTemplate jdbcTemplate;
public void transactionTest()
{
int retCode=0;
try {
retCode = updatedB("param1","param2");
//this.jdbcTemplate.getDataSource().getConnection().commit();
throw new NoClassesException();
}catch (NoClassesException e){
System.out.println(e.getMessage() + "2 patents ");
}
}
public int updatedB(String param1,String param2 )
{
int stat = 0;
stat = this.jdbcTemplate.update("INSERT INTO myTable"
+ "(param1,param2)"
+ " VALUES(?,?)" ,
new Object[] { param1,param2});
return stat;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
public class NoClassesException extends RuntimeException {
public NoClassesException() {
super("Rolled back ");
}
}
and my spring.xml file is:
<?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:tx="http://www.springframework.org/schema/tx"
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-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="controller" class="Controller">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="transaction*" propagation="REQUIRED" rollback-for="NoClassesException" />
<tx:method name="update*" propagation="SUPPORTS" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="myMethods" expression="execution(* *..Controller.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myMethods" />
</aop:config>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
and my database.xml file is:
<?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:tx="http://www.springframework.org/schema/tx"
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-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="dataConfigPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="searchSystemEnvironment" value="true" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="initialSize" value="2" />
<property name="maxActive" value="2" />
<property name="url" value="my connection details" />
<property name="username" value="xxx" />
<property name="password" value="xxx" />
<!-- <property name="defaultAutoCommit" value="false" /> -->
</bean>
</beans>
Your code should be updated such as
public void transactionTest()
{
int retCode=0;
retCode = updatedB("param1","param2");
//this.jdbcTemplate.getDataSource().getConnection().commit();
throw new NoClassesException();
}
public int updatedB(String param1,String param2 )
{
int stat = 0;
stat = this.jdbcTemplate.update("INSERT INTO myTable"
+ "(param1,param2)"
+ " VALUES(?,?)" ,
new Object[] { param1,param2});
return stat;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
Some prehistory..
I have a web-based corporate CRM system written with Spring and Hibernate. There are a lot of tasks that should be done systematically such as reminders or email notifications.. Now it is implemented as a separate Controller wich is called from cron. Everything works fine except of the fact that some of tasks are very "heavy" and take a lot of Tomcat's resources. So I decided to split them into different java console apps. In order to use the same objects and services I splited the main project into separate projects (libraries):
Objects
DAO
In the main project I just added these projects to the BuildPath so I can use all the objects and services without any problem.
Now I started implement the first console utility and facing some issue.. Take a look.
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-service.xml", "spring-hibernate.xml");
try {
MessageSourceEx messageSource = new MessageSourceEx((ResourceBundleMessageSource) ctx.getBean("messageSource"));
ITasksService tasksService = (ITasksService) ctx.getBean("tasksService");
NotificationsService notificationsService = (NotificationsService) ctx.getBean("notificationsService");
List<Task> tasks = tasksService.systemGetList();
for (Task t: tasks) {
Locale userLocale = t.getCreator().getCommunicationLanguageLocale();
EmailNotification reminder = new EmailNotification(t.getCreator().getEmail(),
messageSource.getMessage(userLocale, "notifications.internal.emails.task.subject"),
messageSource.getMessage(userLocale, "notifications.internal.emails.task.text",
t.getCreator().getNickname(),
t.getName(),
t.getDescription(),
AppConfig.getInstance().getUrl(),
t.getId()),
userLocale, t.getCreator());
notificationsService.email.send(reminder);
if (reminder.getState() == EmailNotificationSendState.Sent) {
t.setReminderSent(true);
tasksService.save(t);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
((ConfigurableApplicationContext)ctx).close();
}
System.exit(0);
}
spring-service.xml
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config />
<context:component-scan base-package="com.dao,com.service,com.notifications,com.interfaces" />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="com.Resources" />
</bean>
</beans>
spring-hibernate.xml
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<tx:annotation-driven />
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/hibernate.properties" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${hibernate.connection.driver_class}" />
<property name="url" value="${hibernate.connection.url}" />
<property name="username" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.data.Task</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
DAO
#Component
public class TasksDAO {
/**
* Retrieves a list of tasks
*
* #return List of tasks
*/
#SuppressWarnings({ "unchecked" })
public List<Task> systemGetList() {
Session session = SessionFactoryUtils.getSession(sessionFactory, false);
List<Task> result = null;
Date now = new Date();
Criteria query = session.createCriteria(Task.class)
.add(Restrictions.le("remindTime", DateUtilsEx.addMinutes(now, 3)))
.add(Restrictions.eq("reminderSent", false))
.addOrder(Order.asc("remindTime"));
result = query.list();
if (result == null)
result = new ArrayList<Task>();
return result;
}
}
Service
#Service
public class TasksService implements ITasksService {
/**
*
*/
#Override
public List<Task> systemGetList() {
return tasksDAO.systemGetList();
}
}
It fails with No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:356) exception.. What is interesting - if I add #Transactional to systemGetList() - works fine. But I don't want to add transactions for all select statements...
And the same code (without transaction) works fine on web-site itself..
Any help? Thank you in advance.
You have specified your service methods to be Transactional
<tx:annotation-driven />
Add #Transactional(readOnly = true) on select/read only methods
I newbie in Java please help me to understand how is right. And My English on basic level..
I use OpenShift and before, maybe 2 or more weeks ago all be fine, but last time I have 3 or ~ < 20 errors like this:
maybe something is wrong on OpenShift? or I doing something bad?
Please explain to me why this is happened?:
Caused by: javax.resource.spi.RetryableUnavailableException: IJ000653: The pool has been shutdown (MysqlDS,178e455)
Similar: IJ000453: Unable to get managed connection datasources
<datasource jndi-name="java:jboss/datasources/ShopDS" enabled="${mysql.enabled}"
use-java-context="true" pool-name="MysqlDS" use-ccm="false">
<connection-url>jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}
</connection-url>
<driver>mysql</driver>
<connection-property name="autoReconnect">true</connection-property>
<connection-property name="useUnicode">true</connection-property>
<connection-property name="autoCommit">false</connection-property>
<connection-property name="characterEncoding">UTF-8</connection-property>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>300</max-pool-size>
<flush-strategy>IdleConnections</flush-strategy>
<prefill>true</prefill>
</pool>
<security>
<user-name>${env.OPENSHIFT_MYSQL_DB_USERNAME}</user-name>
<password>${env.OPENSHIFT_MYSQL_DB_PASSWORD}</password>
</security>
<validation>
<valid-connection-checker
class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker" />
<check-valid-connection-sql>SELECT 1</check-valid-connection-sql>
<validate-on-match>true</validate-on-match>
<background-validation>true</background-validation>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter" />
</validation>
<timeout>
<idle-timeout-minutes>60000</idle-timeout-minutes>
</timeout>
</datasource>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect
</property>
<property name="hibernate.connection.datasource">java:jboss/datasources/ShopDS</property>
<property name="hibernate.connection.autoReconnect">true</property>
<property name="hibernate.connection.is-connection-validation-required">true</property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.connection.release_mode">after_statement</property>
<property name="hibernate.connection.useUnicode">true</property>
<property name="hibernate.connection.characterEncoding">utf8</property>
<property name="hibernate.connection.charSet">UTF-8</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.use_sql_comments">false</property>
<property name="hibernate.format_sql">false</property>
<property name="hibernate.current_session_context_class">jta</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<property name="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform</property>
<property name="hibernate.transaction.auto_close_session">true</property>
<property name="hibernate.archive.autodetection">class, hbm</property>
<property name="hibernate.generate_statistics">true</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_minimal_puts">true</property>
<property name="hibernate.cache.use_structured_entries">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.connection.pool_size">20</property>
<property name="hibernate.default_batch_fetch_size">20</property>
<property name="hibernate.max_fetch_depth">6</property>
<mapping class="small.business.dao.entity.Settings" />
</session-factory>
</hibernate-configuration>
spring-jpa-config.xml
<?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:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<jee:jndi-lookup jndi-name="java:/db_EntityManagerFactory" id="entityManagerFactory"
expected-type="javax.persistence.EntityManagerFactory" cache="true" />
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Process the PersistenceUnit and PersistenceContext annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<!-- <bean class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor"> -->
<!-- <property name="sessionFactory" ref="sessionFactory" /> -->
<!-- </bean> -->
<bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator" />
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="java:/TransactionManager" />
<property name="userTransactionName" value="java:jboss/UserTransaction" />
<property name="transactionSynchronizationRegistryName" value="java:jboss/TransactionSynchronizationRegistry" />
</bean>
</beans>
GenericDAO methods called with #Transactional anotation
package small.business.dao;
import java.lang.reflect.ParameterizedType;
import javax.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.exception.GenericJDBCException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import small.business.domainmodel.interfaces.IElement;
/**
*
* #author 452
*/
public abstract class GenericDAO<E extends IElement<?>> {
private static final Logger log = LoggerFactory.getLogger(GenericDAO.class);
protected Class<E> entityClass;
#Autowired
protected EntityManager entityManager;
#Autowired
protected SessionFactory sessionFactory;
#SuppressWarnings("unchecked")
public GenericDAO() {
entityClass = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
#SuppressWarnings("unchecked")
public E getCurrentElement(Long currentElement) {
E element = null;
try {
//element = entityManager.find(entityClass, currentElement);
Session session = sessionFactory.getCurrentSession();
//element = (E) session.load(entityClass, currentElement);
element = (E) session.get(entityClass, currentElement);
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
}
return element;
}
public E saveOrUpdate(E currentElement) throws Exception {
E result;
try {
result = entityManager.merge(currentElement);
} catch (GenericJDBCException e) {
try {
result = entityManager.merge(currentElement);
} catch (GenericJDBCException ex) {
throw new Exception("saveOrUpdate: ", ex);
}
}
return result;
}
public void remove(E currentElement) throws Exception {
E element = entityManager.find(entityClass, currentElement.getId());
entityManager.remove(element);
}
}
StackTrace:
at java.lang.Thread.run(Thread.java:722)
Caused by: java.sql.SQLException: javax.resource.ResourceException: IJ000453: Unable to get managed connection for java:jboss/datasources/ShopDS
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:137)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:276)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:297)
... 161 more
Caused by: javax.resource.ResourceException: IJ000453: Unable to get managed connection for java:jboss/datasources/ShopDS
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.getManagedConnection(AbstractConnectionManager.java:390)
at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.getManagedConnection(TxConnectionManagerImpl.java:368)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:464)
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:129)
... 164 more
Caused by: javax.resource.spi.RetryableUnavailableException: IJ000653: The pool has been shutdown (MysqlDS,178e455)
at org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreArrayListManagedConnectionPool.getConnection(SemaphoreArrayListManagedConnectionPool.java:264)
at org.jboss.jca.core.connectionmanager.pool.AbstractPool.getTransactionNewConnection(AbstractPool.java:495)
at org.jboss.jca.core.connectionmanager.pool.AbstractPool.getConnection(AbstractPool.java:374)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.getManagedConnection(AbstractConnectionManager.java:329)
JBoss AS 7.1.1, MySql 5, Hibernate 4, Spring 3.2.2
Also try to ssh onto your application (rhc ssh {appName}) and see if you can connect to the db by running "mysql" on the console. If necessary, try restarting the mysql cartridge using "rhc cartridge restart mysql-5.1 {appName}". +1 on checking your mysql log for errors as well:
https://openshift.redhat.com/community/faq/how-to-troubleshoot-application-issues-using-logs