0

Hi i am try to insert data using hibernate 4.x and spring 4.x , here is my code

@RunWith(SpringJUnit4ClassRunner.class)
//ApplicationContext will be loaded from "classpath:/app-config.xml"
@ContextConfiguration("/applicationContext.xml")
@ActiveProfiles("dev")
@Transactional
public class UserDAOTest {
    @Autowired
    private UserDAO userDAOImpl;
    @Rollback(false)
    @Test
    public void testSave()
    {
        System.out.println(userDAOImpl);

        User user =new User();
        //User  us=userDAOImpl.get(1);

        User  us=userDAOImpl.save(new User("anil", "[email protected]", "9505485444", "56482", null, null));
        //userDAOImpl.saveOrUpdate(new User("anil", "[email protected]", "9505485444", "56482", null, null));
        System.out.println(us.getUserId());
    }


}

here is save method

public E save(E object) {
        return (E)getCurrentSession().merge(object);
    }

and gessionmethod is

 public Session getCurrentSession() {
        return sessionFactory.openSession();
    }

it working fine if i use saveOrUpdate instead of merge , why it fails for merge?

But if i change my save method like as follows

public E save(E object) {
       // return (E)getCurrentSession().saveOrUpdate(object);.merge(object);

        Session session = getCurrentSession();
        session.saveOrUpdate(object);
        return (E) session.merge(object);
    }

that have syn data with database

2
  • could you post also what error get's thrown on merge? could you post the User class as well Commented Apr 11, 2014 at 19:57
  • i didn't get any error Commented Apr 12, 2014 at 6:28

1 Answer 1

1

Firstly, you shouldn't be opening a session, a session should get created for you because you are using @Transactional. If you are getting an exception because there is no session, you have your transaction management configured incorrectly. You should be using sessionFactory.getCurrentSession();

Secondly, the session.merge() method has a very specific context. You (should) only use merge if you have 2 active versions of a persistent object in your session, and you want hibernate to automatically combine them and save the result. This is not the case here. You have 1 active version of your persistent object, so you should be calling session.createOrUpdate(); in your method above.

Thirdly, it makes no sense to return your object out of your save method as Hibernate should do that automatically for you. Refactor your DAO like this:

public void saveOrUpdate(E object){ getCurrentSession().saveOrUpdate(object) }

Your unit test should look like this:

@Test
public void testDaoSave(){
    User user = new User("anil", "[email protected]", "9505485444", "56482", null, null);
    userDaoImpl.saveOrUpdate(user);
    System.out.println("User ID: " + user.getUserId()
}

Hibernate will automatically update your object's ID after the call to save using a combination of reflection and AOP pointcuts.

TL;DR,

  1. Don't use merge unless you are actually getting MergeConflict exceptions (and even then its most likely an error with your program logic that you actually needing to use merge).

  2. You don't need to return your object from the saveOrUpdate method, Hibernate will automatically update the object's ID once the save is finished.

  3. You shouldn't be opening a session using the SessionFactory, you should get the instance of the currently running session that was created by the @Transactional annotation in your unit tests.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.