I am getting this error
java.lang.NoClassDefFoundError: org/datanucleus/exceptions/NucleusException
My files:
UserDAOImpl.java
public class UserDAOImpl implements UserDAO{
static Logger log = Logger.getLogger(UserDAOImpl.class.getName());
#Autowired
private DataSource dataSource;
private PersistenceManagerFactory persistenceManagerFactory;
HttpServletRequest request;
#Override
public User getUser(String user_name, String user_password) {
PersistenceManager pm = this.persistenceManagerFactory.getPersistenceManager();
try {
Query query = pm.newQuery(User.class);
query.setFilter("userName == userNameParam && userPassword==userPasswordParam");
query.declareParameters("String lastNameParam, String userPasswordParam");
User user = (User) query.execute(user_name,user_password);
log.info(user.getUserEmail()+"..........."+user.getUserProfileName());
return user;
}
finally {
pm.close();
}
}
dispatcher-servlet.xml
<!-- declare mvc to be annotation driven -->
<mvc:annotation-driven/>
<!-- provide Your Base package to scan annotations for components -->
<context:component-scan base-package="com.titas.controller"></context:component-scan>
<mvc:resources location="static/" mapping="static/**"/>
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/login"
p:username="root"
p:password="" />
<bean id="myPmf" class="org.datanucleus.api.jdo.JDOPersistenceManagerFactory" destroy-method="close">
<property name="connectionFactory" ref="dataSource"/>
<property name="nontransactionalRead" value="true"/>
</bean>
<bean id="userDAO" class="com.titas.dao.UserDAOImpl" >
</bean>
User.java
#PersistenceCapable
public class User {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Integer userId=0;
#Persistent
private String userProfileName=null;
#Persistent
private String userEmail=null;
#Persistent
private String userContact=null;
#Persistent
private String userName=null;
#Persistent
private String userPassword=null;
#Persistent
private Integer userRoleId=0;
#Persistent
private String role=null;
MyController.java
#Controller
//#RequestMapping(value = "/test")
public class MyController{
static Logger log = Logger.getLogger(MyController.class.getName());
#Autowired
private UserDAO userDAO;
List<User> allUser = new ArrayList<User>();
I have used jars like:
mysql-connector-java-5.1.6, ojdbc14, jdo-api-3.0.1, aopalliance-1.0, maven-datanucleus-plugin-3.1.0-release, datanucleus-api-jdo-3.0.0-release.
I am very new in JDO.
Please help!!
You need to add the datanucleus-core-3.1.1.jar jar to your classpath.
Related
We are working on a Tapestry5-Spring-Hibernate application.
We are using Tapestry 5.4.1, Spring 4.3.1.RELEASE and Hibernate 4.3.6.Final.
We are using and XML based application.
We are facing the problem that all daos #Autowired into spring services are always null. This will of course generate a NullpointerException everytime a dao is needed to perform an operation on the database.
We used generic service and dao interfaces
Here are the code samples:
Spring config file
<context:annotation-config />
<context:component-scan base-package="org.prism.forecast" />
<context:property-placeholder location="classpath:hibernate.properties" />
<!--Generic DAO -->
<bean id="appDao" primary="true" class="org.prism.forecast.dao.AppDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!--Generic service-->
<bean id="appServiceImpl" class="org.prism.forecast.services.AppServiceImpl">
<property name="dao">
<ref bean="appDao" />
</property>
</bean>
<bean id="requestDao" class="org.prism.forecast.dao.RequestDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="requestServiceImpl" class="org.prism.forecast.services.RequestServiceImpl">
<property name="dao">
<ref bean="requestDao" />
</property>
</bean>
<bean id="SOPUploadDao" class="org.prism.forecast.dao.SOPUploadDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="SOPUploadServiceImpl" class="org.prism.forecast.services.SOPUploadServiceImpl">
<property name="dao">
<ref bean="SOPUploadDao" />
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.prism.forecast.entities" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<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="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager"/>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
Generic DAO Interface
public interface AppDao {
/**
* Finds an object by id
*
* #param <T>
* #param <PK>
* #param type
* #param id
* #return the object
*/
<T, PK extends Serializable> T find(Class<T> type, PK id);
//other methods
}
Generic DAO implementation
#Repository("appDao")
public class AppDaoImpl implements AppDao {
protected static final Logger logger = LoggerFactory.getLogger(RequestDaoImpl.class);
#Inject
protected Session session;
#Resource(name = "sessionFactory")
protected SessionFactory sessionFactory;
/**
* #param sessionFactory the sessionFactory to set
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#SuppressWarnings("unchecked")
public <T, PK extends Serializable> T find(Class<T> type, PK id) {
return (T) session.get(type, id);
}
//other methods
}
Request DAO
public interface RequestDao extends AppDao {
}
Request DAO Implementation
#Repository("requestDao")
public class RequestDaoImpl extends AppDaoImpl implements RequestDao {
}
Generic service
public interface AppService {
/**
* #param <T>
* #param <PK>
* #param type
* #param id
* #return the object
*/
<T, PK extends Serializable> T find(Class<T> type, PK id);
//Other methods
}
Generic service implementation
#Service("appService")
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public class AppServiceImpl implements AppService {
#Autowired
private AppDao dao = null;
/**
* #return the dao
*/
public AppDao getDao() {
return dao;
}
/**
* #param dao
* the dao to set
*/
public void setDao(AppDao dao) {
this.dao = dao;
}
#Override
public <T, PK extends Serializable> T find(Class<T> type, PK id) {
return dao.find(type, id);//dao is null here
}
//other methods
}
Request Service
public interface RequestService extends AppService {
}
Request Service Implementation
#Service("requestService")
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public class RequestServiceImpl extends AppServiceImpl implements RequestService {
#Autowired
private RequestDao dao;
#Override
public Request find(Request request) {
dao.find(request);
}
//other methods
}
Usage in Tapestry pages
public class ManageRequest{
//dao needed for persistence operations
#InjectService("requestService")
protected requestService service;
}
While debugging the application we figured out that the service has been properly injected into the page but the dao has not been injected into the service. Can anybody tell me what is going wrong here?
This looks like Spring configuration issue, could it be that you need to specify sub package of your DAO services explicitly in <context:component-scan ... />, i.e.:
<context:component-scan base-package="org.prism.forecast, org.prism.forecast.dao" />
Some hints: #Autowired service is null, and multiple packages in context:component-scan.
Entity:
package com.test.entity
#Entity
#Table(name="TEST_TABLE")
public class TestTable implements HasMapping, PrimaryKey<Long>, Serializable {
public static final String TABLE_NAME = "TEST_TABLE";
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID", nullable=false)
private Long id;
#Id
#Column(name="Name", nullable=false)
private String name;
#Temporal(value=TemporalType.TIMESTAMP)
#Column(name="CREATE_TIME", nullable=true)
#CreatedDate
private Date createTime;
#Column(name="CREATE_USER", nullable=true, length=32)
#CreatedBy
private String createUser;
#Temporal(value=TemporalType.TIMESTAMP)
#Column(name="LST_UPD_TIME", nullable=true)
#LastModifiedDate
private Date lstUpdTime;
#Column(name="LST_UPD_USER", nullable=true, length=32)
#LastModifiedBy
private String lstUpdUser;
#Column(name="JPA_VERSION", nullable=false)
#Version
private Integer jpaVersion;
......
}
QPath
package com.test.qpath
#Generated("com.mysema.query.codegen.EntitySerializer")
public class QTestTable extends EntityPathBase<TestTable> {
private static final long serialVersionUID = -1751805455;
public static final QTestTable testTable = new QTestTable("testTable");
public final NumberPath<Long> id = createNumber("id", Long.class);
public final DateTimePath<java.util.Date> createTime = createDateTime("createTime", java.util.Date.class);
public final StringPath createUser = createString("createUser");
public final NumberPath<Integer> jpaVersion = createNumber("jpaVersion", Integer.class);
public final DateTimePath<java.util.Date> lstUpdTime = createDateTime("lstUpdTime", java.util.Date.class);
public final StringPath lstUpdUser = createString("lstUpdUser");
public QTestTable(String variable) {
super(TestTable.class, forVariable(variable));
}
#SuppressWarnings("all")
public QTestTable(Path<? extends TestTable> path) {
super((Class)path.getType(), path.getMetadata());
}
public QTestTable(PathMetadata<?> metadata) {
super(TestTable.class, metadata);
}
......
}
Repository
package com.test.repos
public interface RTestTable extends JpaRepository<TestTable, Long>, QueryDslPredicateExecutor<TestTable> {
}
Service
package com.test.service
#Service
public class TestServiceR() {
#Autowired
private RTestTable rTestTable;
public void handler() {
long id = 1;
TestTable t = rTestTable.findone(id);
}
}
package com.test.service
#Service
public class TestServiceQuery() {
#Autowired
private RTestTable rTestTable;
#PersistenceContext
private EntityManager em;
private QTestTable qTestTable = QTestTable.testTable;
public void handler() {
long id = 1;
JPAQuery query = new JPAQuery(em);
TestTable t = query.from(qTestTable).where(qTestTable.id.eq(id)).singleResult(qTestTable);
}
}
spring config
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="#{env.jdbcUrl}" />
<property name="username" value="#{env.jdbcUsername}" />
<property name="password" value="#{env.jdbcPassword}" />
<property name="initialSize" value="1" />
<property name="minIdle" value="#{env['jdbcMinIdle'] ?: 2 }" />
<property name="maxActive" value="#{env['jdbcMaxActive'] ?: 20}" />
<property name="minEvictableIdleTimeMillis" value="#{env['jdbcMinEvictableIdleTimeMillis'] ?: 1800000}" />
<property name="validationQuery" value="#{env['jdbcTestSql']}" />
<property name="testWhileIdle" value="#{env['jdbcTestWhileIdle']?: false}" />
<property name="testOnBorrow" value="#{env['jdbcTestOnBorrow']?: true}" />
<property name="testOnReturn" value="#{env['jdbcTestOnReturn']?: false}" />
<property name="poolPreparedStatements" value="false" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="-1" />
<property name="filters" value="mergeStat,slf4j" />
<property name="connectionProperties" value="druid.stat.slowSqlMillis=1500;druid.stat.logSlowSql=true" />
<property name="timeBetweenLogStatsMillis" value="900000" />
</bean>
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="default" />
<property name="packagesToScan">
<list>
<value>com.sunline.ccs.infrastructure.shared.model</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="#{env['jpaDatabaseType']?:'DEFAULT'}" />
<property name="showSql" value="#{env['jpaShowSql']?:false}" />
</bean>
</property>
</bean>
<bean id="sessionFactory" factory-bean="emf" factory-method="getSessionFactory" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
<jpa:repositories base-package="com.test.repos" />
I test TestServiceR.handler() and TestServiceQuery.handler().
I think they don't start a transaction.
but class TestServiceR are start a transaction.
why? how can i set TestServiceR.handler() don't start a transaction.
TestServiceR calls RTestTable.findOne which extends JpaRepository, which is implemented by SimpleJpaRepository, which is annotated with #Transactional(readOnly = true). So, the transaction is started by SimpleJpaRepository.
Is there a particular reason why you are worried about the transaction, given that it does not affect the application adversely (at least not much)? See the comment history for this Spring Data JPA JIRA issue if you are not convinced.
If you still want to override the default behaviour, you can initialise JPA repositories as #EnableJpaRepositories(enableDefaultTransactions = false) (Java configuration) or <jpa:repositories enable-default-transactions="false" ... /> (XML configuration) to prevent the default implementation from creating transactions by default. See this Spring Data JPA JIRA issue for more details.
I am using a Date dob; field in my pojo class in spring 4.1.6 using maven
below are the files associated with my app.
// this is my pojo class.
package com.aamir;
import java.util.Date;
public class Student {
private String firstName;
private Date dob;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
}
// this is my client class
package com.aamir;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClientStud1 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("s1");
System.out.println(student.getFirstName());
System.out.println(student.getDob());
}
}
// and finally this is my beans.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: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.xsd">
<bean id="s1" class="com.aamir.Student">
<property name="firstName" value="aamir"/>
<property name="dob" value="12-12-1996"/>
</bean>
<bean id="dateEditor"
class="org.springframework.beans.propertyeditors.CustomDateEditor">
<constructor-arg>
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="dd-MM-yyyy"/>
</bean>
</constructor-arg>
<constructor-arg value="true"/>
</bean>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date" value-ref="dateEditor"/>
</map>
</property>
</bean>
</beans>
and I get this exception every time I try to run the client
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.beans.factory.config.CustomEditorConfigurer#0' defined in class path resource [beans.xml]:
Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.util.LinkedHashMap' to required type 'java.util.Map' for property 'customEditors'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.springframework.beans.propertyeditors.CustomDateEditor] to required type [java.lang.Class] for property 'customEditors[java.util.Date]': PropertyEditor [org.springframework.beans.propertyeditors.ClassEditor] returned inappropriate value of type [org.springframework.beans.propertyeditors.CustomDateEditor]
Note that PropertyEditor are stateful, so you should not register instances directly.
Register property editor classes via customEditor property
Add PropertyEditorRegistrars via propertyEditorRegistrars property in CustomEditorConfigurer
As you want to configure the property editor instance, use property editor registrar instead.
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="org.example.CustomDateEditorRegistrar"/>
</list>
</property>
</bean>
As per the official documentation , the recommended way of registering a PropertyEditor is to create a class that implements propertyEditorRegistrar interface. Each propertyEditorRegistrar can register any number of propertyEditors on a given registry.
Two such implementaions are descibed below:
Approach 1: create a generalized class that implements PropertyEditorRegistrar.
This class can be used for any propertyEditor(s), so you can keep this class in your utils.
Lets name it CustomEditorRegistrar and it looks like this:
public class CustomEditorRegistrar implements PropertyEditorRegistrar
{
Class<?> t;
PropertyEditor propertyEditor;
public CustomEditorRegistrar(Class<?> t, PropertyEditor propertyEditor)
{
this.t = t;
this.propertyEditor = propertyEditor;
}
#Override
public void registerCustomEditors(PropertyEditorRegistry registry)
{
registry.registerCustomEditor(t, propertyEditor);
}
}
. The bean definition to register a CustomDateEditor is as below:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="mky.spring.property.editor.date.CustomEditorRegistrar">
<constructor-arg index="0">
<value type="java.lang.Class">java.util.Date</value>
</constructor-arg>
<constructor-arg index="1">
<bean class="org.springframework.beans.propertyeditors.CustomDateEditor">
<constructor-arg index="0">
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="dd-MM-yyyy" />
</bean>
</constructor-arg>
<constructor-arg index="1" value="true" />
</bean>
</constructor-arg>
</bean>
</list>
</property>
</bean>
<bean
name="Customer"
class="mky.spring.property.editor.date.Customer"
p:name="Customer 1"
p:address="CounterHills LA"
p:deliveryDate="12-11-2016"
p:issueDate="12-10-2016" />
Sys-out client:
public class TestGenericClient
{
ApplicationContext ctx;
public TestGenericClient()
{
ctx = new ClassPathXmlApplicationContext("genericPropertyEditorRegistrar-beans.xml");
}
public static void main(String[] args)
{
System.out.println(new TestGenericClient().ctx.getBean("Customer"));
}
}
And the output is this:
Name=Customer 1
Address=CounterHills LA
Issue Date=Wed Oct 12 00:00:00 GST 2016
deliveryDate=Sat Nov 12 00:00:00 GST 2016
Approach2: create a specific propertyEditorRegistrar eg, for Date
public class CustomDateEditorRegistrar implements PropertyEditorRegistrar
{
#Override
public void registerCustomEditors(PropertyEditorRegistry registry)
{
registry.registerCustomEditor(java.util.Date.class, new CustomDateEditor(new SimpleDateFormat("dd-MM-yyyyy"),true));
}
}
And the bean declaration for this specific CustomDateEditor is :
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="mky.spring.property.editor.date.CustomDateEditorRegistrar" />
</list>
</property>
</bean>
Sys-out cleint:
public TestDateClient()
{
ctx = new ClassPathXmlApplicationContext("datePropertyEditorRegistrar-beans.xml");
}
public static void main(String[] args)
{
System.out.println(new TestDateClient().ctx.getBean("Customer"));
}
And the same output :
Name=Customer 1
Address=CounterHills LA
Issue Date=Wed Oct 12 00:00:00 GST 2016
deliveryDate=Sat Nov 12 00:00:00 GST 2016
My config:
<bean parent="cache-template">
<property name="name" value="yagoLabel" />
<property name="cacheMode" value="PARTITIONED" />
<property name="atomicityMode" value="TRANSACTIONAL" />
<property name="distributionMode" value="PARTITIONED_ONLY" />
<property name="backups" value="1" />
<property name="store">
<bean class="id.ac.itb.ee.lskk.lumen.yago.YagoLabelCacheStore" autowire="byType" init-method="init" />
</property>
<property name="writeBehindEnabled" value="true" />
<property name="writeBehindFlushSize" value="102380" />
<property name="writeBehindFlushFrequency" value="30000" />
<property name="writeBehindBatchSize" value="10240" />
<property name="swapEnabled" value="false" />
<property name="evictionPolicy">
<bean class="org.gridgain.grid.cache.eviction.lru.GridCacheLruEvictionPolicy">
<property name="maxSize" value="102400" />
</bean>
</property>
</bean>
And I start GridGain as follows:
My GridCacheStore implementation:
public class YagoLabelCacheStore extends GridCacheStoreAdapter<String, YagoLabel> {
private static final Logger log = LoggerFactory
.getLogger(YagoLabelCacheStore.class);
private DBCollection labelColl;
#GridSpringResource(resourceName="mongoDb")
private DB db;
#Inject
private GridGainSpring grid;
#PostConstruct
public void init() {
log.info("Grid is {}", grid);
labelColl = db.getCollection("label");
}
I start GridGain as follows:
String entityId = "Muhammad";
try (AnnotationConfigApplicationContext appCtx
= new AnnotationConfigApplicationContext(LumenConfig.class)) {
Grid grid = appCtx.getBean(Grid.class);
GridCache<String, YagoLabel> labelCache = YagoLabel.cache(grid);
log.info("Label for {}: {}", entityId, labelCache.get(entityId));
}
LumenConfig Spring configuration contains a DB bean named mongoDb.
However this throws NullPointerException because db is not injected properly. I tried #Inject GridGainSpring just for testing, and even GridGainSpring itself is not injected.
I also tried setting <property name="db" ref="mongoDb"/> in the GridGain Config XML but Spring complains cannot find the bean.
My workaround is to put it inside a public static field but that's soo hacky: https://github.com/ceefour/lumen-kb/blob/b8445fbebd227fb7ac337c758a60badb7ecd3095/cli/src/main/java/id/ac/itb/ee/lskk/lumen/yago/YagoLabelCacheStore.java
The way is to load the GridConfiguration using Spring, then pass it to GridGainSpring.start() :
// "classpath:" is required, otherwise it won't be found in a WAR
#ImportResource("classpath:id/ac/itb/ee/lskk/lumen/core/lumen.gridgain.xml")
#Configuration
public static class GridGainConfig {
#Inject
private ApplicationContext appCtx;
#Inject
private GridConfiguration gridCfg;
#Bean(destroyMethod="close")
public Grid grid() throws GridException {
return GridGainSpring.start(gridCfg, appCtx);
}
}
:-)
I've seen several similar questions, but none of the suggested solutions helped me.
Summary: when I create and inject the beans on the .xml, it works; but when I use #Autowire or #Resource, it doesn't.
Environment: Spring3, Hibernate4, Tomcat7.
Details: the following setup DOES work:
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml
/WEB-INF/spring/users-context.xml
</param-value>
</context-param>
root-context.xml:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/venus" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.airbus.genesis.marte.dal" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
users-context.xml:
<bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
BL object:
#Service("usersManager")
#Transactional(readOnly = true)
public class UsersManager implements IUsersManager {
#Autowired
#Qualifier("usersDAO")
private IUsersDAO usersDAO;
#Override
public List<User> getUsers() {
return usersDAO.getUsers();
}
}
DAO object (notice that #Repository and #Resource are commented):
//#Repository("usersDAO")
#Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {
// #Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
#Override
public List<User> getUsers() {
#SuppressWarnings("unchecked")
List<User> res = (List<User>) getSessionFactory().getCurrentSession()
.createQuery("from User").list();
return res;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
But the following one DOES NOT work:
users-context.xml:
<!--
<bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
-->
DAO object (notice that #Repository and #Resource are uncommented now):
#Repository("usersDAO")
#Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {
#Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
#Override
public List<User> getUsers() {
#SuppressWarnings("unchecked")
List<User> res = (List<User>) getSessionFactory().getCurrentSession()
.createQuery("from User").list();
return res;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
org.hibernate.HibernateException: No Session found for current thread is raised:
org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
com.airbus.genesis.marte.dal.users.UsersDAO.getUsers(UsersDAO.java:23)
com.airbus.genesis.marte.bl.users.UsersManager.getUsers(UsersManager.java:22)
[...]
The same happens if I use #Autowire instead of #Resource.
I guess it is some kind of misunderstanding on my side, but cannot find where. Any idea?
The problem is likely that #Repository and #Service annotations are being picked up in the dispatcher-servlet.xml configuration (do you use context:component-scan?), so these beans are created in the dispatcher servlet context instead of the root web app context.
A good practice is to put your service layer objects to the dedicated packages and use the specific package name as <context:component-scan/> base-package qualifier (like 'com.myproject.services'). You can also use filter expressions to include and exclude elements see examples here : #Service are constructed twice
and 4.10.3 section of the Spring documentation
See also Difference between applicationContext.xml and spring-servlet.xml in Spring Framework