保存到数据库时的Hibernate TransactionException

时间:2016-03-26 17:31:31

标签: java hibernate

我在尝试保存到数据库时遇到了hibernate的问题。我有以下两个类::普通类和测试类::

public class HibernateRankingService2 implements RankingService2{

    public HibernateRankingService2() {
    }

    public void addRanking(String subject, String observer, String skill, int ranking) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.getTransaction();
        addRanking(session, subject, observer, skill, ranking);
        tx.commit();
        session.close();
    }

    private void addRanking(Session session, String subjectName,
        String observerName, String skillName, int rank) {
        Person subject = savePerson(session, subjectName);
        Person observer = savePerson(session, observerName);
        Skill skill = saveSkill(session, skillName);
        Ranking ranking = new Ranking();
        ranking.setSubject(subject);
        ranking.setObserver(observer);
        ranking.setSkill(skill);
        ranking.setRanking(rank);
        session.save(ranking);
    }

    public int getRankingFor(String subject, String skill) {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        int average = getRankingFor(session, subject, skill);
        tx.commit();
        session.close();
        return average;
    }

    private int getRankingFor(Session session, String subject,
        String skill) {
        Query query = session.createQuery("from Ranking r "
                                            + "where r.subject.name=:name "
                                            + "and r.skill.name=:skill");
        query.setString("name", subject);
        query.setString("skill", skill);
        int sum = 0;
        int count = 0;
        for (Ranking r : (List<Ranking>) query.list()) {
            count++;
            sum += r.getRanking();
            System.out.println(r);
        }
        return count == 0 ? 0 : sum / count;
    }   

    private Person findPerson(Session session, String name){
        Query query = session.createQuery("from Person p where p.name=:name");
        query.setParameter("name", name);
        query.setMaxResults(1);
        List<Person> person = (List<Person>)query.list();
        System.out.println("SIZE..: " + query.list().size());
        if(person.size() == 0){
            return null;
        }       
        return person.get(0);
    }

    private Person savePerson(Session session, String name){
        Person person = findPerson(session, name);
        if(person == null){
            person = new Person();
            person.setName(name);
            session.save(person);
        }
        return person;
    }

    private Skill findSkill(Session session, String name){
        Query query = session.createQuery("from Skill s where s.name=:name");
        query.setParameter("name", name);
        query.setMaxResults(1);         
        List<Skill> skill = (List<Skill>)query.list();
        System.out.println("SIZE..: " + query.list().size());
        if(skill.size() == 0){
            return null;
        }       
        return skill.get(0);
    }

    private Skill saveSkill(Session session, String name){
        Skill skill = findSkill(session, name);
        if(skill == null){
            skill = new Skill();
            skill.setName(name);
            session.save(skill);
        }
        return skill;
    }


}

这是测试类::

public class AddRankingTest {

    RankingService2 service = new HibernateRankingService2();

    @Test
    public void addRanking(){
        service.addRanking("J. C. Smell", "Drew Lombardo", "Mule", 8);
        assertEquals(service.getRankingFor("J. C. Smell", "Mule"), 8);
    }

}

我有以下异常::

org.hibernate.TransactionException: Transaction not successfully started
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:59)
    at chapter3.application.HibernateRankingService2.addRanking(HibernateRankingService2.java:29)
    at chapter3.simple_test.AddRankingTest.addRanking(AddRankingTest.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)

...
...

错误来自tx.commit();方法中的public void addRanking(...);,因为如果我将其注释掉,它会正常运行,没有例外,但数据不会保存到数据库中。

我以相同的public void addRanking(...);方法开始并提交事务,但我不明白为什么会收到事务异常。

我做错了什么?

感谢

PersonSkillRanking等对象是普通的Java POJO,只包含getter和setter。

1 个答案:

答案 0 :(得分:1)

我认为在addRanking(..)方法中,Transaction tx = session.getTransaction();之后您错过了调用

  

tx.begin()