HibernateTemplate is null - spring

I am making a web application on STS. I am using jars of Spring 3.1.0 and HIbernate 4.0.1. I am including jars in project build path.
In DAO layer when I am trying to make a HibernateTemplate object , it is not getting instantiate, It is null there. I don't understand why it is null.
Earlier I was getting an error like NoClassDefinitionFound: org.springframework.orm.hibernate3.HibernateTemplate....Then I included these jars in WEB-INF->lib folder and then this error was removed but still hibernateTemplate object is null. Can there be any issue regarding position of beans.xml in project folders. ? Can anyone help me.
Below is code for my beans.xml and Userinfo.java.
[b]Beans.xml[/b]
Only relevant part of bean.xml
<bean id="hibTemplateBean" class="org.springframework.orm.hibernate3.HibernateTemplate" >
<property name="sessionFactory" ref="sfBean" />
</bean>
[b]UserinfoDao.java[/b]
package com.home.dao;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.home.pojo.User;
public class UserinfoDao {
public UserinfoDao() {
super();
}
private static HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
UserinfoDao.hibernateTemplate = hibernateTemplate;
}
public static void fetchUserInfo(){
try{
User user = (User)hibernateTemplate.get(User.class, 111);
}catch(NullPointerException npe){
npe.printStackTrace();
}
}
}

You are using Hibernate 4 and you are using org.springframework.orm.hibernate3.HibernateTemplate from Hibernate 3 package.
This template is not supported anymore. You can do declarative transaction management.

Your version makes me believe that you are simply accessing your bean with static method:
UserinfoDao.fetchUserInfo();
Looks like you are missing few key points of Spring. First of all you should not use static methods and fields, try with the following class:
public class UserinfoDao {
private HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
public void fetchUserInfo(){
try{
User user = (User)hibernateTemplate.get(User.class, 111);
}catch(NullPointerException npe){
npe.printStackTrace();
}
}
}
Now you need to obtain an instance of Spring bean somehow. You cannot simply use new UserinfoDao() operator. You must either declare your bean in XML or via annotations (and declare dependency on HibernateTemplate.
Finally you shouldn't normally catch NullPointerException, but I understand this if for ddebugging purposes.

Related

uniqueResult is deprecated in hibernate 5.2.2 ? how i can do?

hi,everyone i am a newcomer for hibernate. i write code with struts+spring+hibernate ,i encounter a trouble in this code
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.integration.entity.User;
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {
#Override
public User getUser(String name) {
// TODO Auto-generated method stub
String hsql="from User u where u.name='"+name+"'";
User result=(User)((Query) this.getHibernateTemplate().find(hsql)).uniqueResult();
return result;
}
the question is Query and uniqueResult() is deprecated ,how will i modify my code? thanks
The problem is not only in your method. The hole class HibernateDaoSupportis deprecated as it said here
I recommend you to configure your SessionFactory via Spring (as I see you use it) and use createQuery method to pass there your hql. Here is the example:
Configuring session factory:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
p:packagesToScan="-your-model-"
p:hibernateProperties-ref="-your-properties-"
p:dataSource-ref="-your-datasource-"/>
The DAO method:
private final SessionFactory sessionFactory;
// Injecting session factory via constructor
#Autowired
public UserDAO(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
String hql="from User u where u.name=:name";
public User getByUsername(String name) {
return sessionFactory.getCurrentSession()
.createQuery(hql, User.class)
.setParameter("name", name)
.uniqueResult();
}
Also your code us not secure. You should use params of query for preventing sql injections. I show it in my method. Read about session factory and injecting it in DAO.
Good luck.
EDIT
Also it's just an example. You can configure everything as you wish (via java code, not xml for example)

ClassBridge with DAO class injected

I have a Hibernate Search ClassBridge where I want to use #Inject to inject a Spring 4.1 managed DAO/Service class. I have annotated the ClassBridge with #Configurable. I noticed that Spring 4.2 adds some additional lifecycle methods that might do the trick, but I'm on Spring 4.1
The goal of this is to store a custom field into the index document based on a query result.
However, since the DAO, depends on the SessionFactory getting initialized, it doesn't get injected because it doesn't exist yet when the #Configurable bean gets processed.
Any suggestions on how to achieve this?
You might try to create a custom field bridge provider, which could get hold of the Spring application context through some static method. When provideFieldBridge() is called you may return a Spring-ified instance of that from the application context, assuming the timing is better and the DAO bean is available by then.
Not sure whether it'd fly, but it may be worth trying.
Hibernate Search 5.8.0 includes support for bean injection. You can see the issue https://hibernate.atlassian.net/browse/HSEARCH-1316.
However I couldn't make it work in my application and I had implemented a workaround.
I have created an application context provider to obtain the Spring application context.
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public static ApplicationContext getApplicationContext() {
return context;
}
#Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
ApplicationContextProvider.context = context;
}
}
I have added it to the configuration class.
#Configuration
public class RootConfig {
#Bean
public ApplicationContextProvider applicationContextProvider() {
return new ApplicationContextProvider();
}
}
Finally I have used it in a bridge to retrieve the spring beans.
public class AttachmentTikaBridge extends TikaBridge {
#Override
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
// get service bean from the application context provider (to be replaced when HS bridges support beans injection)
ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
ExampleService exampleService = applicationContext.getBean(ExampleService .class);
// use exampleService ...
super.set(name, content, document, luceneOptions);
}
}
I think this workaround it's quite simple in comparision with other solutions and it doesn't have any big side effect except the bean injection happens in runtime.

org.springframework.orm.hibernate3.HibernateTemplate

We are using hibernate template by using the following package.
org.springframework.orm.hibernate3.HibernateTemplate;
protected HibernateTemplate template = null;
here template is from org.springframework.orm.hibernate3.HibernateTemplate package. I am not able to understand how to interpret this package.
is it the spring hibernate because package name starts with springframework. But there is no such spring hibernate. There is only ORM module i guess in spring.
Can anyone help me understand how to understand this package org.springframework.orm.hibernate3.HibernateTemplate.
update:
below is the exactly repository class I am using
#Repository
#Transactional
public class ABCDImplements ABCD {
private Log logger = LogFactory.getLog(this.getClass());
protected HibernateTemplate template = null;
#Resource(name = "abcSessionFactory")
protected SessionFactory sessionFactory;
#Autowired
public void init(SessionFactory sessionFactory) {
setSessionFactory(sessionFactory);
}
public void setSessionFactory(SessionFactory sessionFactory) {
template = new HibernateTemplate(sessionFactory);
}
}
Spring provides integration with Hibernate 3 and 4 under the form of HibernateTemplate, and the one you show provides integration with Hibernate 3.
The main goal of this class was to provide a Hibernate session via a callback, and another important functionality was to translate Hibernate exceptions to Spring exceptions.
The use of this class is not recommended anymore, have a look at this answer. The recommended way is to use the #Transactional annotation.

How do I dynamically create dependency implementations as they are referenced in Spring?

The situation here is that I have an interface that has dynamic implementations. These implementations need to be instantiated at runtime and used by injecting the interface:
public interface Configuration {
void doStuff();
}
public interface ExampleConfiguration extends Configuration {
void doStuff();
}
ExampleConfiguration has an implementation generated dynamically. I.e, there is no ExampleConfigurationImpl class. This is proving difficult to integrate into Spring because I want to have these generated implementations injected automatically:
#Autowired
private ExampleConfiguration config;
I went down the road of adding a BeanPostProcessor but it looks like unresolved dependencies don't go through there (as I would expect).
Essentially, is there a way to contribute a factory that will be called (with contextual information such as a DependencyDescriptor instance) in an attempt to resolve a missing dependency? There will be multiple interfaces extending the Configuration interface.
Spring version is 3.0.3.
Have you tried a FactoryBean?
public class ExampleConfigurationFactoryBean implements FactoryBean<ExampleConfiguration> {
#Override
public ExampleConfiguration getObject() throws Exception {
return //...magic here
}
#Override
public Class<?> getObjectType() {
return ExampleConfiguration.class;
}
#Override
public boolean isSingleton() {
return true;
}
}
I don't know how you actually create these dynamic beans (I suspect some dynamic proxy being involved), but insert your logic in magic here placeholder. Should work. You use the FactoryBean as if it had a target type in your XML:
<bean id="exampleConfigurationFactoryBean" class="ExampleConfigurationFactoryBean"/>
<bean id="someBean">
<!-- exampleConfiguration is of ExampleConfiguration type -->
<property name="exampleConfiguration" ref="exampleConfigurationFactoryBean"/>
</bean>
Spring will call getObject() when requested.
I assume you've got some way to actually manufacture the instances? Well, all you need to do is to make that factory into a bean itself and add the right annotations:
#org.springframework.context.annotation.Configuration
public class ConfigBean {
#org.springframework.context.annotation.Bean
public ExampleConfiguration getObject() throws Exception {
return //...magic here
}
}
You use the usual Spring techniques for hooking to any configuration you need. (I assume you're using <context:component-scan> and <context:annotation-config>…)

MyBatis-Spring + #Configuration - Can't autowire mapper beans

I have been trying to create a Spring project that uses MyBatis for the data access layer as a proof of concept for my team. I really want to avoid XML configuration if at all possible, so I'm attempting to wire everything together using annotated #Configuration classes.
Everything seems to be wired correctly, but my mapper beans are not being AutoWired into my service layer.
In my example I'm trying to wire together a UserDao, User entity, and a UserService.
UserDao
public interface UserDao {
#Select("SELECT * FROM users WHERE id = #{userId}")
User get(#Param("userId") Integer userId);
}
User
#Component("User")
public class User implements Entity {
public Integer userId;
public String username;
/** ... getters/setters ommitted **/
}
UserServiceImpl
#Service("UserService")
public class UserServiceImpl {
private UserDao userDao = null;
public User getUserDetails(Integer userId) {
return userDao.get(userId);
}
#Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
I'm wiring these together using two configuration classes.
ApplicationContextConfig
#Configuration
#EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
#Import(DefaultDataAccessConfig.class) // I'm importing this because I thought ordering might be important, otherwise I was hoping to just let the component scanning pull in additional configuration files
#ComponentScan(basePackages="com.example.gwtspringpoc.server",
excludeFilters=#Filter(type=FilterType.ANNOTATION,
value=Controller.class))
public class ApplicationContextConfig {
/** No bean definitions needed here **/
}
DefaultDataAccessConfig
#Configuration
#EnableTransactionManagement
public class DefaultDataAccessConfig implements TransactionManagementConfigurer {
#Bean
public DataSource dataSource() {
OracleDataSource ods = null;
try {
ods = new OracleDataSource();
} catch (SQLException e) {
throw new RuntimeException(e);
}
ods.setURL("jdbc:oracle:thin:#//localhost:9601/sid");
ods.setUser("user");
ods.setPassword("pass");
return ods;
}
#Override
#Bean(name="transactionManager")
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager(dataSource());
}
#Bean
public SqlSessionFactory sqlSessionFactory() {
SqlSessionFactoryBean sf = new SqlSessionFactoryBean();
sf.setDataSource(dataSource());
try {
return (SqlSessionFactory) sf.getObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Bean
public SqlSession sqlSessionTemplate() {
return new SqlSessionTemplate(sqlSessionFactory());
}
/*
* This did not work at all. It seems to be configured correctly, but the UserDao bean never
* got created at any stage, which was very disappointing as I was hoping not to have to
* create a bean definition for each DAO manually
*/
/*#Bean
public static MapperScannerConfigurer mapperScannerConfig() {
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.ca.spna.gwtspringpoc.server.model.dao");
msc.setAnnotationClass(Repository.class);
return msc;
}*/
/*
* Because the above code did not work, I decided to create the mapping manually.
* This is most likely my problem - something about this setup. My understanding
* is that the MapperFactoryBean once instantiated by Spring, will create a proxy
* object of type UserDao with the name "userDao" that can be injected elsewhere.
*/
#Bean
public MapperFactoryBean<UserDao> userDao() {
MapperFactoryBean<UserDao> mfb = new MapperFactoryBean<UserDao>();
mfb.setMapperInterface(UserDao.class);
return mfb;
}
}
You can read the comments above the last two methods in the above code snippet to gain more insight into how I'm creating the UserDao bean.
Once I got all the configuration setup, I created a unit test to try to test the UserService using the AnnotationConfigContextLoader, but was immediately hit with the following exception when trying to run the test:
Exception
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.example.gwtspringpoc.server.service.UserServiceImpl.setUserDao(com.example.gwtspringpoc.server.model.dao.UserDao); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.example.gwtspringpoc.server.model.dao.UserDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
After seeing that, I commented out the #Autowired in the UserService and went back to my unit test and injected the ApplicationContext so I could inspect it, and the bean named "userDao" is in fact a MapperProxy instance.
So, is my understanding of how the MapperFactoryBean works off track or is it just not very compatible with annotation driven configuration? Additionally, if anyone has any idea how to make the MapperScannerConfigurer work correctly, I would appreciate it greatly!
After some time I was able to figure things out, so I'll answer my own question in case others run into something similar as there wasn't a whole lot of information available out there and it took some searching.
The problem comes down to the fact that MapperScannerConfigurer is a BeanDefinitionRegistryPostProcessor. As it turns out, this is the same mechanism used to process the #Configuration files and register the #Bean annotated methods. Unfortunately, one BeanDefinitionRegistryPostProcessor cannot make use of another, according to this Spring Jira ticket: https://jira.springsource.org/browse/SPR-7868
The suggestion here was to create an XML configuration for the processor and then include an #ImportResource annotation in the Java based configuration to pull it in. Well, that suggestion isn't fully accurate. You can't simply create an XML file with the configuration and pull it into the Java based configuration if you are still planning to have your configuration bootstrapped via an AnnotationConfigContextLoader. Instead, you have to revert back to loading your configuration via XML first and then creating a bean for your configuration file(s) the "old-fashion" way. For me this, was pretty trivial.
New Application Context
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!--
Because MapperScannerConfigurer is a BeanDefinitionRegistryPostProcessor, it cannot be
configured via #Configuration files with a #Bean annotaiton, because those files are
themselves configured via a BeanDefinitionRegistryPostProcessor which cannot spawn
another one.
-->
<bean id="myBatisMapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.gwtspringpoc.server.model.dao"/>
<property name="annotationClass" value="org.springframework.stereotype.Repository"/>
</bean>
<!--
Load the rest of our configuration via our base configuration class
-->
<bean class="com.example.gwtspringpoc.server.spring.config.ApplicationContextConfig" />
</beans>
I then bootstrap the context container the traditional way, by providing a ContextConfigLocation. This works for me because the ApplicationContextConfig that I reference in the above XML handles everything else - including component scanning which will pick up all of my other #Configuration files.
Once I did this, all of my problems went away. I was able to #Autowire the UserDao as I expected and all was wonderful.
Note:
When I tried manually defining UserDao by creating a MapperFactoryBean, like in my original question's code example, there was a UserDao bean created but it was of type MapperProxy and would not #Autowire. However, I could get it to load by name using #Repository("userDao"), for what that's worth. I believe that the MapperFactoryBean suffers from a similar problem as the MapperScannerConfigurer and is simply not compatible with #Configuration files, alas.
From mybatis.3.2.0 and mybatis-spring.1.2.0,
instead of MapperFactoryBean, you can use MapperScan for this.
#Configuration
#MapperScan("org.mybatis.spring.sample.mapper")
public class AppConfig
{
#Bean
public DataSource dataSource()
{
return new EmbeddedDatabaseBuilder().addScript("schema.sql").build();
}
#Bean
public DataSourceTransactionManager transactionManager()
{
return new DataSourceTransactionManager(dataSource());
}
#Bean
public SqlSessionFactory sqlSessionFactory() throws Exception
{
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
return sessionFactory.getObject();
}
}
Another possible solution can be found in the jira ticked that Jason mentioned. Solved my problem and I did not have to use XML configuration which I try to avoid at any cost...
https://jira.spring.io/browse/SPR-7868
#Configuration
public class A implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
#Override
public void postProcessBeanDefinitionRegistry(...) {
...
}
#Override
public void postProcessBeanFactory(...) {
...
}
#Override
public int getOrder() {
return 0;
}
}
You'll have to have a context:component-scan in your spring configurations to enable auto detection of #Component . Check the reference.

Resources