Perhaps this question has been asked severally but am not able to find a solution to this. I am new to Spring and trying to working on a simple project to integrate Spring with Hibernate 4 using annotations. Whenever i click the user form to save to DB it throws this exception:
HTTP Status 500 - Request processing failed; nested exception is org.hibernate.HibernateException: saveOrUpdate is not valid without active transaction
What am I doing wrong? My code is below:
User.java
#Entity
#Table(name="SpringUsers")
public class User implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "userId")
private int id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "email")
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
UsDAOImpl.java
#Repository
public class UserDAOImpl implements UserDAO{
#Autowired
private SessionFactory sessionFactory;
public UserDAOImpl(){}
public UserDAOImpl( SessionFactory sessionFactory){
this.sessionFactory= sessionFactory;
}
#Override
#Transactional
public List<User> list() {
List<User> listUser = sessionFactory.getCurrentSession()
.createCriteria(User.class).list();
return listUser;
}
#Override
#Transactional
public void saveOrUpdate(User user) {
sessionFactory.getCurrentSession().saveOrUpdate(user);
}
#Override
#Transactional
public void delete(int id) {
User userToDelete = new User();
userToDelete.setId(id);
sessionFactory.getCurrentSession().delete(userToDelete);
}
#Override
#Transactional
public User get(int i) {
String hql = "from User where id=" + i;
Query query = sessionFactory.getCurrentSession().createQuery(hql);
List<User> listUser = (List<User>) query.list();
if (listUser != null && !listUser.isEmpty()) {
return listUser.get(0);
}
return null;
}
}
user-servlet.xml
<context:component-scan base-package="com.myspringapp.controller"/>
<mvc:annotation-driven/>
<context:annotation-config />
<!-- <tx:annotation-driven />-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:XE"/>
<property name="username" value="system"/>
<property name="password" value="henry"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.myspringapp.model.User</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<constructor-arg ref="sessionFactory"/>
</bean>
<bean id="userDao" class="com.myspringapp.dao.UserDAOImpl">
<constructor-arg ref="sessionFactory"/>
</bean>
<!-- <tx:annotation-driven transaction-manager="transactionManager"/>-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
Uncomment this line and it should work:
<tx:annotation-driven />
Related
I am trying to create a project with embedded h2 db, and using spring framework with hibernate. My database will be created in initialize time if not exist. My development platform is intellij.
Problem is that when i run the application
#Autowired
private IPersonService personService; // comes null?
here is my classes and config files.
myDB.sql:
CREATE TABLE IF NOT EXISTS personel(
id IDENTITY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
age VARCHAR(100));
hibernate.properties:
db.driverClassName=org.h2.Driver
db.url=jdbc:h2:~/h2SpringProject/database/SpringSample;mv_store=false;mvcc=false
db.username=admin
db.password=
here is my hibernate-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
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 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.springapp"/>
<context:annotation-config/>
<context:property-placeholder location="hibernate.properties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
<property name="driverClassName" value="${db.driverClassName}"></property>
<property name="url" value="${db.url}"></property>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="suppressClose" value="true"/>
</bean>
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="myDb.sql"/>
</jdbc:initialize-database>
<bean id="hibernateCfgProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</prop>
</props>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties" ref="hibernateCfgProperties"/>
<property name="packagesToScan" value="com.springapp.model"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
Person class
#Entity
#Table(name = "personel")
public class Personel {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "name")
private String name;
#Column(name = "age")
private String age;
.......
An IPersonDao interface and here is implemented class
#Component
public class PersonelDaoImpl implements IPersonelDao {
#Autowired
private SessionFactory sessionFactory;
public Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
#Override
public void savePersonel(Personel personel) {
getCurrentSession().saveOrUpdate(personel);
}
#Override
public void deletePersonel(long id) {
getCurrentSession().delete(id);
}
#Override
public List<Personel> getPersonels() {
return getCurrentSession().createQuery("from Personel").list();
}
}
There is an IPersonService interface and here is implemented class
#Service("PersonelService")
public class PersonelServiceImpl implements IPersonelService {
#Autowired
private IPersonelDao personelDao;
#Override
#Transactional
public void savePersonel(Personel personel) {
personelDao.savePersonel(personel);
}
#Override
#Transactional
public void deletePersonel(long id) {
personelDao.deletePersonel(id);
}
#Override
#Transactional
public List<Personel> getPersonels() {
return personelDao.getPersonels();
}
}
here is my main class
public class MainApp {
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = new ClassPathXmlApplicationContext("hibernate-config.xml");
ForExample a = new ForExample();
a.execute();
}
}
#Component
public class ForExample {
#Autowired
private IPersonelService personelService;
public void execute(){
Personel p = new Personel();
p.setName("thats Ok!");
p.setAge("614345");
personelService.savePersonel(p);
}
}
public class MainApp {
public static ApplicationContext applicationContext;
private static IPersonelService personelService;
public static void main(String[] args) {
applicationContext = new ClassPathXmlApplicationContext("hibernate-config.xml");
personelService = applicationContext.getBean(IPersonelService.class);
Personel p = new Personel();
p.setName("thatsOK!");
p.setAge("614345");
personelService.savePersonel(p);
}
}
Because of spring does not recognise new operator in run time..
I have following spring configuration.
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="nestedTransactionAllowed" value="true" />
</bean>
<bean id='entityManagerFactory'
class='org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean'>
<property name="persistenceUnitName" value="test" />
<property name='dataSource' ref='dataSource' />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
</bean>
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/testdb" />
<property name="username" value="test" />
<property name="password" value="test" />
</bean>
And i have created following entity.
#Entity(name="testtable")
public class Testtable implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private int testid;
#Column(length=10)
private String description;
public Testtable() {
}
public int getTestid() {
return this.testid;
}
public void setTestid(int testid) {
this.testid = testid;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
Now I want to test the nested transaction behavior with this setup. So I have created following test class.
#TransactionConfiguration(defaultRollback=false)
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath:context-test.xml")
public class TableTest {
#Autowired
private TesttableRepository testtableRepository;
#Test
#Transactional
public void testMethod()
{
Testtable entry = new Testtable();
entry.setDescription("ABC");
entry = testtableRepository.save(entry);
TestObj t = new TestObj(testtableRepository);
t.testNestedTransactional();
entry.setDescription("ABCEE");
testtableRepository.save(entry);
assertNotNull(entry.getTestid());
}
}
public class TestObj {
public TestObj(TesttableRepository testtableRepository){
this.testtableRepository = testtableRepository;
}
private TesttableRepository testtableRepository;
#Transactional(propagation=Propagation.NESTED )
public void testNestedTransactional(){
Testtable entry1 = new Testtable();
entry1.setDescription("RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
testtableRepository.save(entry1);
}
}
The testNestedTransactional() method in TestObj.java should fail because of database constraint violation (Max length for field description is 10). Even though this method fail I expect "ABCEE" value to be saved in database. Is this correct with nested transaction behavior? How can I achieve this goal?
The problem is that you create TestObj manually. You should do it using Spring context (declare it in context as a bean and autowire in the test).
Spring will wrap this bean in a proxy to make it transactional. In your case it is a plain old Java object without transactional behavior.
I have some code on Spring/Hibernate/Jersey. I want Hibernate to generate my tables. This is my User entity
#Entity
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private String id;
private String email;
private String nickname;
private String password;
#OneToOne(cascade=CascadeType.ALL)
private PersonalInfo personalInfo;
#OneToOne(fetch=FetchType.LAZY ,cascade=CascadeType.ALL)
private AccountInfo accountInfo;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public PersonalInfo getPersonalInfo() {
return personalInfo;
}
public void setPersonalInfo(PersonalInfo personalInfo) {
this.personalInfo = personalInfo;
}
public AccountInfo getAccountInfo() {
return accountInfo;
}
public void setAccountInfo(AccountInfo accountInfo) {
this.accountInfo = accountInfo;
}
public User(){
}
}
And this is my configuration:
<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/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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<tx:annotation-driven/>
<context:component-scan base-package="com.weproj" />
<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/DB" />
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.weproj.model"/>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
It generates the tables when the #GeneratedValue(strategy=GenerationType.IDENTITY) is removed but it does not when I set it.
If you want to use generated value for primary key or something like that try to use Integer in both the table structure and Java.
private String id;
try to make it
private int id;
make sure you have designed the User table similarly(Integer and auto generated ).
I use Spring 3 and Hibernate 4. I try to save a Users entity in database but it's not working. When i call the method finUsersByUsername(String username) it's work well. But when i use the save method defined in GenericDao it's does not work. I don't understand it. If someone could help me ?
Domain class users:
#Entity
#Table(name="USERS")
public class Users{
#Id
#Column(name="USERNAME", length=50,nullable=false )
private String username;
#Column(name="PASSWORD",length=50, nullable=false)
private String password;
#Column(name="ENABLED", nullable=false)
private Boolean enabled;
#Column(name="LASTNAME",length=50)
private String lastName;
#Column(name="FIRTSNAME",length=50)
private String firstName;
#Column(name="DATEOFBIRTH")
private Date dateOfBirth;
#Column(name="EMAIL",length=50, nullable=false)
private String email;
#Column(name="PHONENUMBER",length=50)
private String phoneNumber;
... getters and setters
}
Generic DAO interface :
public interface GenericDao<T, PK extends Serializable> {
PK create(T newInstance);
T read(PK id);
List<T> readAll();
List<T> readByCriteria(Criterion criterion);
void update(T transientObject);
void delete(T persistentObject);
}
DAO implementation:
#Repository
public class GenericDaoImpl<T, PK extends Serializable> implements GenericDao<T, PK> {
#Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
private Class<T> type;
public GenericDaoImpl() {
super();
}
public GenericDaoImpl(Class<T> type) {
this.type = type;
}
#Transactional
#SuppressWarnings("unchecked")
public PK create(T object) {
return (PK) getSession().save(object);
}
#SuppressWarnings("unchecked")
public T read(PK id) {
return (T) getSession().get(type, id);
}
public List<T> readAll() {
return readByCriteria();
}
#SuppressWarnings("unchecked")
public List<T> readByCriteria(Criterion... criterion) {
Criteria crit = getSession().createCriteria(type);
for (Criterion c : criterion) {
crit.add(c);
}
return crit.list();
}
#Transactional
public void update(T object) {
getSession().update(object);
}
#Transactional
public void delete(T object) {
getSession().delete(object);
}
public Session getSession() {
return sessionFactory.openSession();
}
}
Users DAO Interface:
public interface UserDao extends GenericDao<Users, Long> {
Users finUsersByUsername(String username);
}
Users Dao implementations
#Repository
#Transactional
public class UserDaoImpl extends GenericDaoImpl<Users, Long> implements UserDao{
#Autowired
private SessionFactory sessionFactory;
public UserDaoImpl(){}
#SuppressWarnings("unused")
private Class<Users> type;
public UserDaoImpl(Class<Users> type) {
super(type);
}
#Override
public Users finUsersByUsername(String username) {
return (Users) sessionFactory.getCurrentSession().load(Users.class,username);
}
}
Spring configuration 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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!-- Configuration des annotations -->
<context:annotation-config />
<!-- Activation du scan des annotations Spring MVC -->
<context:component-scan base-package="com.nexthome.app"/>
<bean id="userDao" class="com.nexthome.app.dao.hibernate.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/home"/>
<property name="username" value="postgres"/>
<property name="password" value="database"/>
</bean>
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.nexthome.app.dao.entities.Users</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- Resolveur de vues -->
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsps/"
p:suffix=".jsp" />
</beans>
Thanks for your help
This method is probably the root cause:
public Session getSession() {
return sessionFactory.openSession();
}
Spring instantiates a session at start of the Transaction. When opening your own session, it won't be managed by Springs Transaction abstraction. Use the existing session instead of creating a new one. Probably changing method to this does the trick:
public Session getSession() {
return sessionFactory.getCurrentSession();
}
See also: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/orm.html#orm-hibernate
I really want to understand what is going on with my code.
I have a standalone application which uses spring and Hibernate as JPA and I am trying to run the test using a single main Class
My main class
package edu.acct.tsegay.common;
import edu.acct.tsegay.model.User;
import edu.acct.tsegay.business.IUserBusinessObject;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
try {
ApplicationContext context = new ClassPathXmlApplicationContext(
"Spring3AndHibernate-servlet.xml");
IUserBusinessObject userBusinessObject = (IUserBusinessObject) context
.getBean("userBusiness");
User user = (User) context.getBean("user1");
user.setPassword("pass");
user.setUsername("tsegay");
System.out.println(user.getPassword());
userBusinessObject.delete(user);
User user2 = new User();
user2.setUsername("habest");
user2.setPassword("pass1");
System.out.println(user2.getPassword());
/*
* userBusinessObject.save(user2);
*
* User user3 = userBusinessObject.searchUserbyId("tsegay");
* System.out.println("Search Result: " + user3.getUsername());
*/
System.out.println("Success");
} catch (Exception e) {
e.printStackTrace();
}
}
}
my application context is:
<beans xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd">
<!-- data source -->
<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/test" />
<property name="username" value="test" />
<property name="password" value="password" />
</bean>
<!-- session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- exposed person business object -->
<bean id="userBusiness" class="edu.acct.tsegay.business.UserBusinessObject">
<property name="userDao" ref="userDao" />
</bean>
<bean id="user1" class="edu.acct.tsegay.model.User">
<property name="username" value="tse" />
<property name="password" value="pass" />
</bean>
<!-- Data Access Object -->
<bean id="userDao" class="edu.acct.tsegay.dao.UserDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
My User Model is:
package edu.acct.tsegay.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
import org.hibernate.annotations.NaturalId;
#Entity
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String username;
private String password;
private Integer VERSION;
#Version
public Integer getVERSION() {
return VERSION;
}
public void setVERSION(Integer vERSION) {
VERSION = vERSION;
}
#NaturalId
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
My DAO is:
package edu.acct.tsegay.dao;
import edu.acct.tsegay.model.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
#Repository
public class UserDao implements IUserDao {
private SessionFactory sessionFactory;
private HibernateTemplate hibernateTemplate;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
public void save(User user) {
// TODO Auto-generated method stub
// getHibernateTemplate().save(user);
this.hibernateTemplate.save(user);
}
public void delete(User user) {
// TODO Auto-generated method stub
this.hibernateTemplate.delete(user);
}
public User searchUserbyId(String username) {
// TODO Auto-generated method stub
return this.hibernateTemplate.get(User.class, username);
}
}
And this my stacktrace error when i run the program:
pass
org.springframework.orm.hibernate3.HibernateSystemException: Unknown entity: edu.acct.tsegay.model.User; nested exception is org.hibernate.MappingException: Unknown entity: edu.acct.tsegay.model.User
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:679)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:837)
at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:833)
at edu.acct.tsegay.dao.UserDao.delete(UserDao.java:34)
at edu.acct.tsegay.business.UserBusinessObject.delete(UserBusinessObject.java:30)
at edu.acct.tsegay.common.App.main(App.java:23)
Caused by: org.hibernate.MappingException: Unknown entity: edu.acct.tsegay.model.User
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:580)
at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1365)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:100)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:74)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:793)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:771)
at org.springframework.orm.hibernate3.HibernateTemplate$25.doInHibernate(HibernateTemplate.java:843)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
... 6 more
You have to list your classes in your session factory configuration. You can have your entities auto-discovered if you are using EntityManager.
In order to use annotations with hibernate and spring, you have to use AnnotationSessionFactoryBean:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="annotatedClasses">
<list>
<value>edu.acct.tsegay.model.User</value>
</list>
</property>
....
</bean>
Also, it is rather strange that your User entity is a spring bean. You don't need that. Hibernate entities are supposed to be created with the new operator.
I've encountered the same problem and didn't find any good answer for this
What worked for me was to declare my entity class in the persistence.xml file:
<persistence ...>
<persistence-unit ...>
<class>com.company.maenad.core.model.News</class>
<class>com.company.maenad.core.model.AdExtraInfo</class>
</persistence-unit>
</persistence>
In addition to Bozho answer, if you are using spring + hibernate with annotation then in your session factory bean you can register your bean like below:
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(appContext.getBean(HikariDataSource.class));
localSessionFactoryBean.setAnnotatedClasses(
AppUser.class, Assignment.class
);