I need in my application to remove all data from a cachable table.
I suposed that to delete all contents, I had to remove the second level cache, then use a truncate.
#Entity
#Table(name = "\"cpf_formacode\"")
#Cacheable
public class CpfRefFormaCode implements Serializable {
.......
}
the Dao method:
public void deleteAll() {
SessionFactory sf = em.unwrap(SessionFactory.class);
sf.getCache().evictEntityRegion(CpfRefFormaCode.class);
em.createNativeQuery("TRUNCATE TABLE cpf_formacode").executeUpdate();
}
persistence file:
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="org.hibernate.FlushMode" value="commit" />
<!-- property name="hibernate.hbm2ddl.auto" value="create-drop" / -->
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/hibernate" />
<property name="hibernate.cache.region.factory_class" value="org.jboss.as.jpa.hibernate4.infinispan.InfinispanRegionFactory" />
<property name="hibernate.cache.infinispan.statistics" value="true" />
</properties>
the error i have :
17:50:17,161 ERROR [org.jboss.as.ejb3.tx.CMTTxInterceptor] (http--127.0.0.1-8080-2) javax.ejb.EJBTransactionRolledbackException: Hibernate cannot unwrap interface org.hibernate.SessionFactory
17:50:17,163 ERROR [org.jboss.ejb3.invocation] (http--127.0.0.1-8080-2) JBAS014134: EJB Invocation failed on component CpfRefFormaCodeDao for method public void com.agefos.corp.business.dao.CpfRefFormaCodeDao.deleteAll(): javax.ejb.EJBTransactionRolledbackException: Hibernate cannot unwrap interface org.hibernate.SessionFactory
Caused by: javax.persistence.PersistenceException: Hibernate cannot unwrap interface org.hibernate.SessionFactory
I finished by findig the solution,
The problem that i was trying to clean the cach before deleting the data, and it was not the best practice
public void deleteAll() {
try {
TypedQuery<MyEntity> query = em.createQuery("From MyEntity f", MyEntity.class);
query.setHint("org.hibernate.cacheable", true);
List<MyEntity> result = null;
result = query.getResultList();
if (!result.isEmpty()) {
for (MyEntity f : result) {
em.remove(f);
}
}
em.flush();
} catch (Exception e) {
throw new PersistanceException("An error occurred while attempting to delete an instance of an object : " + entityClass, e);
}
}
the problem was resolved by adding the
em.flush();
In other words, flush tells Hibernate to execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held in the session-level cache. so i was abel to save other entities without ID problems
Related
I want to use entity manager from container, but when I try to access it I get
java.lang.IllegalStateException: Need active coordination
persistence.xml
<persistence-unit name="data-point" transaction-type="JTA">
<jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=dvdrental)</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.archive.autodetection" value="class"/>
</properties>
bluprint.xml
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"
default-activation="eager"
xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.2.0"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0">
<jpa:enable />
<tx:enable-annotations />
<service id="filesEntityManager" ref="filesEntityManagerImpl" interface="ru.bia.karaf.dao.FilesEntityManager"/>
<bean id="filesEntityManagerImpl" class="ru.bia.karaf.dao.FilesEntityManagerImpl"/>
<bean id="testBean" class="ru.bia.karaf.web.TestBean" init-method="test">
<property name="filesEntityManager" ref="filesEntityManagerImpl"/>
</bean>
TestBean.java
public class TestBean {
private FilesEntityManagerImpl filesEntityManager;
public void test(){
System.out.println("hey bro from init");
System.out.println("filesEntityManager = " + filesEntityManager);
System.out.println("filesEntityManager.getEm() = " + filesEntityManager.getEm());
}
public FilesEntityManagerImpl getFilesEntityManager() {
return filesEntityManager;
}
public void setFilesEntityManager(FilesEntityManagerImpl filesEntityManager) {
this.filesEntityManager = filesEntityManager;
}
}
FilesEntityManagerImpl.java
#OsgiServiceProvider(classes = {FilesEntityManager.class})
#Transactional
public class FilesEntityManagerImpl implements FilesEntityManager {
#PersistenceContext(unitName="data-point")
EntityManager em;
...
}
The EntityManager that is injected into FilesEntityManagerImpl is a thread local proxy of the EntityManager. Its lifecycle is bound to a Coordination.
If you access em outside of a Coordination you get this error. You can make sure a Coordination is active by using the #Transactional annotations. If you
do not need an actual transaction but only the Coordination then use #Transactional(TxType.SUPPORTS).
You should also generally not access the EntityManager outside of the object that is injected with it.
I am stuck into a big trouble that i cannot connect the oracle 11g database form my Spring MVC application.
The error i am getting is
HTTP Status 500 - Request processing failed; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
also,
in the stack trace i'm getting the error-
java.lang.ClassNotFoundException: oracle.jdbc.OracleDriver
If you can help me to resolve the issue, it will be a great help.
I am providing my configuration and coding details below:
Default-servlet.xml
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="testConnectionOnCheckout" value="${jdbc.testConnection}" />
</bean>
<bean id="userAuthenticationRepository"
class="com.era.repository.impl.UserAuthenticationRepositoryImpl">
<property name="dataSource" ref="dataSource" />
</bean>
UserAuthenticationRepositoryImpl.java
#Repository
public class UserAuthenticationRepositoryImpl implements UserAuthenticationRepository {
#Qualifier("dbDataSource")
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public User getUserAuthentication(User userToBeAuthenticated) {
// TODO Auto-generated method stub
String query = "select id, name, role from User where login =";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
StringBuilder queryString = new StringBuilder();
queryString.append(" SELECT ")
.append( "*" )
.append(" FROM table_name ")
.append(" WHERE login = ? ");
Object[] parameterList = { userToBeAuthenticated.getLogin() };
SqlRowSet dataRow = jdbcTemplate.queryForRowSet(queryString.toString(), parameterList);
if (dataRow.next()) {
System.out.println("Query executed successfully");
}
return null;
}
As you are using maven, note here you can't directly get Oracle driver jar to .m2 due to licence restriction, so you may need to manually download and place it to your repository.You may find this link helpful.
I fighing with hibernate. I'm trying to follow hibernate.org/ogm/documentation/getting-started/ . Here are my files
- persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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_2_0.xsd">
<persistence-unit name="ogm-jpa-tutorial" transaction-type="JTA">
<!-- Use Hibernate OGM provider: configuration will be transparent -->
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<class>com.mycompany.hibernate.MyEntity</class>
<properties>
<property name="hibernate.ogm.datastore.provider" value="MONGODB"/>
<!-- property optional if you plan and use Infinispan, otherwise adjust to your favorite
NoSQL Datastore provider.
<property name="hibernate.ogm.datastore.provider"
value="org.hibernate.ogm.datastore.infinispan.impl.InfinispanDatastoreProvider"/>
-->
<!-- defines which JTA Transaction we plan to use -->
<property name="hibernate.ogm.datastore.provider" value="org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastoreProvider"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
entity class:
#Entity
#Table(name = "USstates")
public class MyEntity implements Serializable{
#Id
String _id;
String city;
Integer pop;
String state;
public String getId(){return _id;}
public String getCity(){return city;}
public Integer getPop(){return pop;}
public String getState(){return state;}
}
application
private static final String JBOSS_TM_CLASS_NAME = "com.mycompany.hibernate.TransactionManager";
public static void main( String[] args ) throws Exception
{
EntityManagerFactory emf = Persistence.createEntityManagerFactory(
"ogm-jpa-tutorial");
TransactionManager tm = getTransactionManager();
//Persist entities the way you are used to in plain JPA
tm.begin();
EntityManager em = emf.createEntityManager();
MyEntity e = new MyEntity();
e = new MyEntity();
//Retrieve your entities the way you are used to in plain JPA
tm.begin();
em = emf.createEntityManager();
e = em.find(MyEntity.class, "0");
em.flush();
em.close();
tm.commit();
emf.close();
}
public static TransactionManager getTransactionManager() {
try {
Class<?> tmClass = App.class.getClassLoader().loadClass( JBOSS_TM_CLASS_NAME );
return (TransactionManager) tmClass.getMethod( "transactionManager" ).invoke( null );
} catch ( ClassNotFoundException e ) {
e.printStackTrace();
} catch ( InvocationTargetException e ) {
e.printStackTrace();
} catch ( NoSuchMethodException e ) {
e.printStackTrace();
} catch ( IllegalAccessException e ) {
e.printStackTrace();
}
return null;
}
I have database test with collection USstates taken from http://media.mongodb.org/zips.json
Using thic codes I got some wornings about logs and what more important exception while running this application:
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: ogm-jpa-tutorial] Unable to build Hibernate SessionFactory
any ideas?
UPDATE:
after fighting i got an error of non exising class, I already tried milions of combinations of dependency and still got nothing... error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/hibernate/util/xml/Origin
UPDATE 2.0:
Now I have other problem:
Exception in thread "main" java.lang.NoSuchMethodError: org.hibernate.cfg.Configuration.getIdentifierGeneratorFactory()Lorg/hibernate/id/factory/spi/MutableIdentifierGeneratorFactory;
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1119)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:291)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:373)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:55)
at org.hibernate.ogm.jpa.HibernateOgmPersistence.createEntityManagerFactory(HibernateOgmPersistence.java:92)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
at com.mycompany.hibernate.App.main(App.java:48)
Ok silly question - did you remove the specific connection properties from your persistence.xml here, or did you not have them - example below?
<property name="hibernate.ogm.datastore.provider" value="mongodb"/>
<property name="hibernate.ogm.datastore.database" value="rntsmpl"/>
<property name="hibernate.ogm.datastore.host" value="127.0.0.1"/>
<property name="hibernate.ogm.datastore.port" value="59541"/>
<property name="hibernate.ogm.datastore.username" value="admin"/>
<property name="hibernate.ogm.datastore.password" value="nnTdE2jPf4FV"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
I'm trying to catch a ConstraintViolationException in my service layer and rethrowing a user defined checked exception. I'm catching the exception in my controller and adding an error object to my BindingResult. I'm using declarative transaction management I've tried to make my DAO a Repository and added a PersistenceExceptionTranslationPostProcessor to catch a spring translated exception. I've also added a txAdvice to rollback on all throwables. My exception does get caught but I'm getting an error 500 with:
Hibernate: insert into user (email, password, first_name, last_name, userType) values (?, ?, ?, ?, 1)
[acme]: [WARN ] - 2013-Feb-05 11:12:43 - SqlExceptionHelper:logExceptions(): SQL Error: 1062, SQLState: 23000
[acme]: [ERROR] - 2013-Feb-05 11:12:43 - SqlExceptionHelper:logExceptions(): Duplicate entry 'admin' for key 'email_unique'
[acme]: [DEBUG] - 2013-Feb-05 11:12:43 - HibernateTransactionManager:processCommit(): Initiating transaction commit
[acme]: [DEBUG] - 2013-Feb-05 11:12:43 - HibernateTransactionManager:doCommit(): Committing Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]
[acme]: [ERROR] - 2013-Feb-05 11:12:43 - AssertionFailure:<init>(): HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in com.test.model.AdminUser entry (don't flush the Session after an exception occurs)
[acme]: [DEBUG] - 2013-Feb-05 11:12:43 - HibernateTransactionManager:doRollbackOnCommitException(): Initiating transaction rollback after commit exception
org.hibernate.AssertionFailure: null id in com.test.model.AdminUser entry (don't flush the Session after an exception occurs)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:79)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:194)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:156)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:225)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:468)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
My Controller:
#RequestMapping (method = RequestMethod.POST)
#Transactional
public String registerAdmin(#Valid #ModelAttribute("user") AdminUser user, BindingResult bindingResult, ModelMap model) {
if (bindingResult.hasErrors()) {
return "admin/admins/form";
}
else if (!user.getPassword().equals(user.getConfirmPassword())) {
bindingResult.addError(new ObjectError("user.confirmPassword", "Passwords don't match"));
return "admin/admins/form";
}
else {
user.setPassword(passwordEncoder.encodePassword(user.getPassword(), null));
try {
userService.save(user);
return "redirect:/admin/admins";
} catch(ApplicationException ce) {
bindingResult.addError(new ObjectError("user.email", "Email already registered"));
return "admin/admins/form";
}
}
}
Part of my Spring config:
<context:component-scan base-package="com.test.dao, com.test.service" />
<context:property-placeholder location="/WEB-INF/spring.properties"/>
<import resource="springapp-security.xml"/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/testdb?zeroDateTimeBehavior=convertToNull"/>
<property name="username" value="test"/>
<property name="password" value="test"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingLocations" value="classpath*:com/test/model/hbm/**/*.hbm.xml" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
</value>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*" rollback-for="Throwable" />
</tx:attributes>
</tx:advice>
Service layer:
public class UserServiceImpl implements UserDetailsService, UserService {
private UserDAO dao;
#Override
public void save(User c) throws ApplicationException {
try {
dao.save(c);
} catch(DataIntegrityViolationException cve) {
throw new ApplicationException("email already registered");
}
}
If I don't catch the runtime exception I don't get the hibernate exception (don't flush the session..)
You may want to remove the transaction annotation from your controller and add it to the service layer.
The service layer would look like below. If your service layer is throwing a checked exception you can add that to your annotation so that the insert is not even attempted to be committed.
public class UserServiceImpl implements UserDetailsService, UserService {
private UserDAO dao;
#Override
#Transactional(rollbackFor=ApplicationException.class)
public void save(User c) throws ApplicationException {
try {
dao.save(c);
} catch(DataIntegrityViolationException cve) {
throw new ApplicationException("email already registered");
}
}
What is happening currently in your code is that the transaction is not being rolled back but has to rollback because it actually tried to commit the data but because a database constraint the transaction had to be rolled back. By forcing the rollback with the #Transactional(rollbackFor=ApplicationException.class) it will not allow the transaction to perform a commit but it will rollback and your app will still add the error to the BindingResult.
I'm using persistence in a project for school, and I have a problem when I'm try to deleting and updating object, all others queries works.
The exception is :
Illegal attempt to associate a collection with two open sessions
I close every session I have opened.
HibernateUtils code
public class Hibernate
{
protected static final SessionFactory sessionFactory;
private Session session;
static
{
try
{
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
session
}
catch (Throwable ex)
{
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public void create(Object obj)
{
this.session = sessionFactory.openSession();
session.getTransaction().begin();
session.save(obj);
session.getTransaction().commit();
session.close();
}
public void refresh(Object obj)
{
this.session = sessionFactory.openSession();
session.getTransaction().begin();
session.refresh(obj);
session.getTransaction().commit();
session.close();
}
public void update(Object obj)
{
this.session = sessionFactory.openSession();
session.getTransaction().begin();
session.saveOrUpdate(obj);
session.getTransaction().commit();
session.close();
}
public void delete(Object obj)
{
this.session = sessionFactory.openSession();
session.getTransaction().begin();
session.delete(obj);
session.flush();
session.getTransaction().commit();
session.close();
}
protected String protectString(String toProtect)
{
return (toProtect.replace("'", "''"));
}
}
DAOPerson :
public class DAOPerson extends Hibernate
{
public void remove(Person p)
{
if (p instanceof Student)
{
Student s = (Student)p;
Set<persistenceClass.Class> set = s.getClasses();
Iterator<persistenceClass.Class> it = set.iterator();
while (it.hasNext())
{
persistenceClass.Class r = it.next();
r.getStudents().remove(s);
}
p.getBirthCountry();
p.getCountry();
this.delete(p);
}
else
this.delete(p);
}
For information my mapping file of students is :
<class name="persistenceClass.Person" table="T_PERSON">
<id name="Id" column="PERSON_ID">
<generator class="native" />
</id>
<property name="FirstName" column="PERSON_FIRST_NAME" not-null="true" />
<property name="LastName" column="PERSON_LAST_NAME" not-null="true" />
<property name="Type" column="PERSON_TYPE" not-null="true" />
<property name="BirthDate" column="PERSON_BIRTH_DATE" />
<property name="BirthCity" column="PERSON_BIRTH_CITY" />
<property name="PhoneNumber" column="PERSON_PHONE_NUMBER" />
<property name="MobileNumber" column="PERSON_MOBILE_NUMBER" />
<property name="Mail" column="PERSON_MAIL" />
<property name="Address" column="PERSON_ADDRESS_ADDRESS" />
<property name="ZipCode" column="PERSON_ADDRESS_ZIPCODE" />
<property name="City" column="PERSON_ADDRESS_CITY" />
<property name="Image" column="PERSON_IMAGE" type="image" />
<many-to-one name="Country" column="PERSON_ADDRESS_COUNTRY" class="persistenceClass.Country" />
<many-to-one name="BirthCountry" column="PERSON_BIRTH_COUNTRY" class="persistenceClass.Country" />
<many-to-one name="Civility" column="PERSON_CIVILITY" class="persistenceClass.Civility" />
<many-to-one name="Sex" column="PERSON_SEX" class="persistenceClass.Sex" />
<joined-subclass name="persistenceClass.Student" table="T_STUDENT">
<key column="PERSON_ID" />
<set name="Classes" table="T_CLASS_STUDENT" inverse="true" >
<key column="PERSON_ID" />
<many-to-many class="persistenceClass.Class" column="CLASS_ID" />
</set>
</joined-subclass>
<joined-subclass name="persistenceClass.Teacher" table="T_TEACHER">
<key column="PERSON_ID" />
</joined-subclass>
</class>
And the main mapping file :
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/projet</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">10</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<!-- Drop and re-create the database schema on start-up, also try with “update” to keep the previous values -->
<property name="hbm2ddl.auto">update</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping resource="persistenceConfigurations/Person.hbm.xml"/>
<mapping resource="persistenceConfigurations/Country.hbm.xml"/>
<mapping resource="persistenceConfigurations/Civility.hbm.xml"/>
<mapping resource="persistenceConfigurations/Sex.hbm.xml"/>
<mapping resource="persistenceConfigurations/Formation.hbm.xml"/>
<mapping resource="persistenceConfigurations/Year.hbm.xml"/>
<mapping resource="persistenceConfigurations/Class.hbm.xml"/>
<mapping resource="persistenceConfigurations/Subject.hbm.xml"/>
<mapping resource="persistenceConfigurations/Room.hbm.xml"/>
<mapping resource="persistenceConfigurations/Lesson.hbm.xml"/>
</session-factory>
</hibernate-configuration>
I try a lot of configuration but I've everytime the same exception, if somebody have an idea, I want it !
Thanks !
Sorry for my bad english
The session is not meant to be used for one call and closed. Using the utility class as a base for your POJO is not a good idea.
The entity that is being deleted should use the same session that it was retrieved from or at least be refreshed on the new session before being removed.
Also the iterating through the removal of the dependent 'Class' entities should be replaced with a cascade REMOVE.
Try using getCurrentSession() instead of openSession() and remove the session.close(); statement.
for starters I think it's a good idea to refactor the name you are giving to the concept of Class (path persistenceClass.Class). In java world 'Class' is actually a class. That may cause some havoc in the future.
One problem I realized on your DAOPerson code is that it looks strange. I understood you're trying to remove the current student from its classes, correct? if so, try the following patch on your code:
public void remove(Person p)
{
if (p instanceof Student)
{
Student s = (Student)p;
Set<persistenceClass.Class> set = s.getClasses();
Iterator<persistenceClass.Class> it = set.iterator();
while (it.hasNext())
{
persistenceClass.Class r = it.next();
r.getStudents().remove(s);
//now effectively removing the student from the class.
//this will update the class and its persistent set of students.
this.update(r);
}
}
this.delete(p); //now remove the student (or whatever comes as argument)
}
Now another possible problem: your HibernateUtils is not treating transactions properly. You should refactor your code to look like the following:
//Example
public void create(Object obj){
this.session = sessionFactory.openSession();
try{
session.getTransaction().begin();
session.save(obj);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
session.flush();
session.close();
//keep in mind that too many flushes might cause db memory shortage.
//So if you are treating list of objects and so on iterate and save them flushing
//only when your batch size is reached.
}
}
Hope that helps!
I notice that you haven't defined lazy=false in you person mapping file, so I assume you are using lazy loading attribute for the property Set. You say you have closed all sessions before a call to remove, then how come you are able to access the property s.getClasses() in the remove() method of DAOPerson without throwing a lazyInitializationException. If you forgot to mention lazy=false in the mapping file, then my observations do not count. If that is not the case, then you surely do have a session open somewhere to which the Person p (passed to the DAOs remove method) is associated. At the end of this method, when you try to re-attach the object with another session you get an exception.
The problem was due to a misuse of cascade update in one of the mappings. Here is a sample field mapping:
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = “user_id”)
public User getAuthor() {
return author;
}
Removing the cascade = CascadeType.ALL fixed the problem. Conclusion: carefully use cascade updates as it may get you into trouble. Use it when business logic requires it. In the example below there was no need for it, so removing it was both business and programatically a good decision.
Source: http://blog.tremend.ro/2007/03/05/illegal-attempt-to-associate-a-collection-with-two-open-sessions/