Hibernate - Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1

前端 未结 30 3645
夕颜
夕颜 2020-11-28 20:47

I get following hibernate error. I am able to identify the function which causes the issue. Unfortunately there are several DB calls in the function. I am unable to find the

相关标签:
30条回答
  • 2020-11-28 21:28

    After reading all answers did´t find anyone to talk about inverse atribute of hibernate.

    In my my opinion you should also verify in your relationships mapping whether inverse key word is appropiately setted. Inverse keyword is created to defines which side is the owner to maintain the relationship. The procedure for updating and inserting varies cccording to this attribute.

    Let's suppose we have two tables:

    principal_table, middle_table

    with a relationship of one to many. The hiberntate mapping classes are Principal and Middle respectively.

    So the Principal class has a SET of Middle objects. The xml mapping file should be like following:

    <hibernate-mapping>
        <class name="path.to.class.Principal" table="principal_table" ...>
        ...
        <set name="middleObjects" table="middle_table" inverse="true" fetch="select">
            <key>
                <column name="PRINCIPAL_ID" not-null="true" />
            </key>
            <one-to-many class="path.to.class.Middel" />
        </set>
        ...
    

    As inverse is set to ”true”, it means “Middle” class is the relationship owner, so Principal class will NOT UPDATE the relationship.

    So the procedure for updating could be implemented like this:

    session.beginTransaction();
    
    Principal principal = new Principal();
    principal.setSomething("1");
    principal.setSomethingElse("2");
    
    
    Middle middleObject = new Middle();
    middleObject.setSomething("1");
    
    middleObject.setPrincipal(principal);
    principal.getMiddleObjects().add(middleObject);
    
    session.saveOrUpdate(principal);
    session.saveOrUpdate(middleObject); // NOTICE: you will need to save it manually
    
    session.getTransaction().commit();
    

    This worked for me, bu you can suggest some editions in order to improve the solution. That way we all will be learning.

    0 讨论(0)
  • 2020-11-28 21:30

    In my case, I came to this exception in two similar cases:

    • In a method annotated with @Transactional I had a call to another service (with long times of response). The method updates some properties of the entity (after the method, the entity still exists in the database). If the user requests two times the method (as he thinks it doesn't work the first time) when exiting from the transactional method the second time, Hibernate tries to update an entity which already changed its state from the beginning of the transaction. As Hibernate search for an entity in a state, and found the same entity but already changed by the first request, it throws an exception as it can't update the entity. It's like a conflict in GIT.
    • I had automatic requests (for monitoring the platform) which update an entity (and the manual rollback a few seconds later). But this platform is already used by a test team. When a tester performs a test in the same entity as the automatic requests, (within the same hundredth of a millisecond), I get the exception. As in the previous case, when exiting from the second transaction, the entity previously fetched already changed.

    Conclusion: in my case, it wasn't a problem which can be found in the code. This exception is thrown when Hibernate founds that the entity first fetched from the database changed during the current transaction, so it can't flush it to the database as Hibernate doesn't know which is the correct version of the entity: the one the current transaction fetch at the beginning; or the one already stored in the database.

    Solution: to solve the problem, you will have to play with the Hibernate LockMode to find the one which best fit your requirements.

    0 讨论(0)
  • 2020-11-28 21:32

    This happens to me because I am missing ID declaration in bean class.

    0 讨论(0)
  • 2020-11-28 21:33

    I ran into this issue when I was manually beginning and committing transactions inside of method annotated as @Transactional. I fixed the problem by detecting if an active transaction already existed.

    //Detect underlying transaction
    if (session.getTransaction() != null && session.getTransaction().isActive()) {
        myTransaction = session.getTransaction();
        preExistingTransaction = true;
    } else {
        myTransaction = session.beginTransaction();
    }
    

    Then I allowed Spring to handle committing the transaction.

    private void finishTransaction() {
        if (!preExistingTransaction) {
            try {
                tx.commit();
            } catch (HibernateException he) {
                if (tx != null) {
                    tx.rollback();
                }
                log.error(he);
            } finally {
                if (newSessionOpened) {
                    SessionFactoryUtils.closeSession(session);
                    newSessionOpened = false;
                    maxResults = 0;
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 21:33

    One of the case

    SessionFactory sf=new Configuration().configure().buildSessionFactory();
    Session session=sf.openSession();
    
    UserDetails user=new UserDetails();
    
    session.beginTransaction();
    user.setUserName("update user agian");
    user.setUserId(12);
    session.saveOrUpdate(user);
    session.getTransaction().commit();
    System.out.println("user::"+user.getUserName());
    
    sf.close();
    
    0 讨论(0)
  • 2020-11-28 21:35

    It also can happen when you try to UPDATE a PRIMARY KEY.

    0 讨论(0)
提交回复
热议问题