I'm curious what should be result when I create object, Then I delete object and then I try to load this object from database. I guess it should be "null". In one table I receive "null" in second table i receive nothing.
Create:
public void createPerson(Person p) {
session.beginTransaction();
session.save(p);
session.getTransaction().commit();
logger.info("Person saved successfully!");
}
Delete:
public void deletePerson(int id) {
session.beginTransaction();
Person p = getPersonById(id);
if(p != null){
session.delete(p);
session.getTransaction().commit();
}
if(getPersonById(id) == null){
logger.info("Person deleted successfully!");
}else{
logger.info("Something went wrong! Person hasn't been deleted!");
}
}
and load:
public Person getPersonById(int id) {
session.beginTransaction();
Person p = (Person) session.load(Person.class, id);
logger.info("Person loaded successfully!");
return p;
}
And I receive nothing. What is the problem?
As per my understanding you should flush your context after create/delete operation.The flush process synchronizes database state with session state by detecting state changes and executing SQL statements.
if(p != null){
session.delete(p);
session.getTransaction().commit();
session.setFlushMode(FlushModeType.COMMIT);
}
You can read about flush mode Hibernate flush mode.
Where is the commit in deletePerson? and the commit again in getPersonById?
Fix the code you would see that you don't get the entity back by ID one you delete it.
Related
I have a DAO User with Hibernate framework.
I am doing some Junit test about it. Testing create/update/delete on user, works for create but not for update and delete but my test passed.
I need to verify what is wrong with my update, delete functions.
I tried to add a session.save() befose the update NOK
I tried to replace session.update() to session.saveOrUpdate() NOK
I tried to use the user parameter instead of create a new user NOK
Junit function update/delete only displaying update and delete
#Test
public void testCreateUpdateDeleteUser(){
User userCRUD = new User("morganeflamant#gmail.com", "admin", new
Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()));
userCRUD = serviceFacade.getUserDao().findUserById(userCRUD.getId_user());
Assert.assertNotNull(userCRUD);
userCRUD.setId_user(userCRUD.getId_user());
userCRUD.setEmail("testmorgane#gmail.com");
userCRUD.setRole("member");
userCRUD = serviceFacade.getUserDao().updateUser(userCRUD);
Assert.assertNotNull(userCRUD);
Assert.assertNotNull(userCRUD.getUpdateAt());
userCRUD = serviceFacade.getUserDao().findUserById(userCRUD.getId_user());
Assert.assertTrue(serviceFacade.getUserDao().deleteUser(userCRUD));
}
Userdao update and delete function:
#Override
public User updateUser(User user) {
Session session = SingletonHibernate.getSessionFactory().openSession();
session.beginTransaction();
User u = new User(user.getId_user(), user.getEmail(), user.getRole(), user.getCreateAt(), user.getUpdateAt());
u.setId_user(user.getId_user());
u.setEmail(user.getEmail());
u.setRole(user.getRole());
u.setCreateAt(user.getCreateAt());
u.setUpdateAt(user.getUpdateAt());
session.saveOrUpdate(u);
session.close();
return u;
}
#Override
public boolean deleteUser(User user) {
Session session = SingletonHibernate.getSessionFactory().openSession();
session.beginTransaction();
User u = (User) session.get(User.class, user.getId_user());
if(u != null){
session.delete(u);
return true;
}
return false;
}
In my db I actually have :
60
morganeflamant#gmail.com
admin
2019-07-19 13:38:19
2019-07-19 13:38:19
but I am supposed to have this:
60
testmorgane#gmail.com
admin
2019-07-19 13:38:19
2019-07-19 13:38:19
for the update part and the delete part I am not supposed to have the user 60.
UPDATE:
adding this line :
session.getTransaction().commit();
after the session.save() and the changes are done.
Thank you for your comments !
Tag is an entity and I remove tags with this method:
public static <T> boolean deleteById(Class<? extends BaseEntity> clazz, Long id) {
Session session = HibernateUtil.getSessionFactory().openSession();
try {
session.beginTransaction();
T e = get(clazz, id);
if (e != null) {
session.delete(e);
session.getTransaction().commit();
return true;
} else {
return false;
}
} finally {
session.close();
}
}
Next thing, I read the list with Tags again with this method:
public static List<Tag> listTags() {
Session session = HibernateUtil.getSessionFactory().openSession();
Query q = session.createQuery("FROM Tag tag");
List<Tag> tags = (List<Tag>) q.list();
session.close();
return tags;
}
The problem is that when deleting and reselecting all Tags the removed Tag is in the list although not in the database. when I run listTags() a second time, by clicking a link the object is removed and I get the correct list.
Does anyone know why?
Try to add flush() and use commit() like below:
...
session.delete(e);
session.flush();
session.beginTransaction().commit();
...
For more info go to session.getTransaction() vs session.beginTransaction()
I had a similar problem with Hibernate while migration from MySQL to MariaDB, were multiple transactions were being open and not closed...
the solution was removing the opening of the transactions as they were not required anyway....
In Hibernate after session.save(obj) without committing the transaction. If I close the session, when I try to fetch, I will get the data which is in session, i.e the object I didn't commit including that
public static void insert() {
Session session = Hibernateutil.getSessionFactory().openSession;
Leave leave = new Leave();
leave.setUser("nat");
session.save(leave);
session.close();
}
public static List fetch() {
Session session = Hibernateutil.getSessionFactory().openSession;
List li = session.createQuery("from Leave").list();
}
Now I am using jpa with hibernate , when i was done getEntityManager.persist(objects) then i will ask for user confirmation like continue and rollback using user interface
private List<TempCustomers> tempCustomer =new ArrayList<TempCustomers>();
#Begin(join = true)
public String migrateData() {
log.info("Mobee Migrate Customer Size :"+doTempCustomers.size());
for(DoTempCustomers tempCustomers:doTempCustomers){
try {
TempCustomers temp=new TempCustomers();
BeanUtils.copyProperties(temp, tempCustomers);
tempCustomer.add(temp);
getEntityManager().persist(temp);
}catch (Exception e) {
// TODO: handle exception
return "null";
}
}
log.info("Size........."+tempCustomer.size());
return "null";
}
#Begin(join = true)
public String updatedData(){
log.info("Size of Customers :"+tempCustomer.size());
log.info("Decision ..."+decision);
try{
if(decision.equals("Continue")){
for(TempCustomers tempCust:tempCustomer){
TempCustomers temp=new TempCustomers();
BeanUtils.copyProperties(temp, tempCust);
log.info("updated Sucessfully");
getEntityManager().getTransaction().commit();
}}else{
getEntityManager().getTransaction().rollback();
}
}
catch(Exception e){
}
}
please help me how to do continue and rollback in jpa with hibernate when getEntityManager().persist() is done.
To commit with JPA:
entityManager.getTransaction().commit();
To rollback with JPA:
entityManager.getTransaction().rollback();
Call either of these methods after your call to persist to perform the desired action. In your case entityManager would be replaced with the call to retrieve the entityManager, getEntityManager()
Reference: http://www.objectdb.com/java/jpa/persistence/store
Trying to understand more about Hibernate,I wrote some code which creates some entities and saves them in db and then tries to delete one of the entities.
The mapping file for entity Customer has id generator set to native.I am using postgresql as db.
...
<class name="Customer" table="CUSTOMER">
<id column="CUSTOMER_ID" name="customer_id" type="java.lang.Long">
<generator class="native"/>
</id>
...
I came across hibernate.NonUniqueObjectException.
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.me.hibernatestore.Customer#129]
Full stack trace here
I fired up the eclipse debugger and found that the object involved has same address in all the involved methods ..
The relevant part of the code is
public class Main {
CustomerDao custdao;
Customer mark;
public void storeDemo(){
custdao = DaoFactory.getCustomerDao();
createCustomers();
updateEntities();
deleteCustomer(mark);
}
private void createCustomers() {
mark = new Customer();
mark.setName("mark");
mark.setEmailAddress("mark#home");
mark.setAddress("121,3rd avenue");
mark.setCity("San Diego");
mark.setState("CA");
mark.setCountry("U.S.A");
}
private void updateEntities() {
Transaction tx = null;
Session session = HibernateUtil.getCurrentSession();
try{
tx = session.beginTransaction();
custdao.saveOrUpdateCustomer(mark);
tx.commit();
}catch(RuntimeException e){
tx.rollback();
throw e;
}
}
private void deleteCustomer(Customer cust){
Transaction tx = null;
Session session = HibernateUtil.getCurrentSession();
try{
tx = session.beginTransaction();
String custName = cust.getName();
custdao.deleteCustomer(cust);
tx.commit();
}catch(RuntimeException e){
tx.rollback();
throw e;
}
}
public static void main(String[] args) {
new Main().storeDemo();
}
}
With the help of debugger I found the address of object 'mark'
Main.createCustomers(): mark-> Customer#2bc3f5
CustomerDaoImpl.saveOrUpdateCustomer(Customer customer):customer-> Customer#2bc3f5
BaseDaoImpl.saveOrUpdate(T obj):obj-> Customer#2bc3f5
Main.deleteCustomer(Customer customer):customer-> Customer#2bc3f5
CustomerDaoImpl.deleteCustomer(Customer customer):customer-> Customer#2bc3f5
BaseDaoImpl.delete(T obj):obj-> Customer#2bc3f5
Experimenting further,I modified the code and through dao.findById() got a different object with same id and used that in deleteCustomer().This time the code worked without throwing any exception
public class Main {
CustomerDao custdao;
Customer mark;
public void storeDemo(){
custdao = DaoFactory.getCustomerDao();
createCustomers();
updateEntities();
Long mark_id = mark.getCustomer_id();
Customer mark2 = getCustomer(mark_id);
deleteCustomer(mark2);
}
private Customer getCustomer(Long id){
Transaction tx = null;
Customer cust = null;
Session session = HibernateUtil.getCurrentSession();
try{
tx = session.beginTransaction();
return custdao.findCustomerById(id);
}catch(RuntimeException e){
throw e;
}
}
...
}
Can someone explain this behaviour?My understanding about the 'a different object with the same identifier value' part of the error message is fuzzy ..The object as shown in debugger in the first case has same memory address everywhere in the code.Then how can it be a different object?
sincerely
Jim
This exception usually occurs when dealing with detached objects. In order to avoid that, you have to get the object and delete it in the same session or reattach it to the session and then delete it.
Hope this helps!