用hibernate的uuid注解生成主键, save时提示id出错 10C

使用hibernate uuid注解 自动生成id值,在students和courses多对多的级联保存时, id保存出错
报错代码如下

 log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: 
    insert 
    into
        students
        (sname, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        courses
        (cname, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        courses
        (cname, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        students_courses
        (sid, cid) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        students_courses
        (sid, cid) 
    values
        (?, ?)
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:171)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at com.caidi.Test.TestManyToManyEach.test01(TestManyToManyEach.java:41)
    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)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.sql.BatchUpdateException: Field 'id' doesn't have a default value
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1693)
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1108)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
    ... 31 more

  1. Students类
 package com.caidi.beans;

import java.util.List;




import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.GenericGenerator;


@Entity
@Table(name="students")
public class Students {

    @Id
    @GeneratedValue(generator="system-uuid")  
    @GenericGenerator(name="system-uuid", strategy = "uuid.hex") 
    @Column(name="id")
    private String id;

    @Column(name="sname")
    private String sname;

    @ManyToMany
    @Cascade(value={CascadeType.SAVE_UPDATE})
    @JoinTable(name="students_courses",joinColumns={@JoinColumn(name="sid",referencedColumnName="id")},inverseJoinColumns={@JoinColumn(name="cid",referencedColumnName="id")})
    private List<Courses> courses;

    public Students() {
        super();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public List<Courses> getCourses() {
        return courses;
    }

    public void setCourses(List<Courses> courses) {
        this.courses = courses;
    }

}

  1. Courses类
 package com.caidi.beans;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.GenericGenerator;


@Entity
@Table(name="courses")
public class Courses {
    @Id
    @GeneratedValue(generator="system-uuid")  
    @GenericGenerator(name="system-uuid", strategy = "uuid.hex") 
    @Column(name="id")
    private String id;

    @Column(name="cname")
    private String cname;

    @ManyToMany(mappedBy="courses")//ManyToMany默认lazy加载
    @Cascade(value={CascadeType.SAVE_UPDATE})
    private List<Students> students;

    public Courses() {
        super();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public List<Students> getStudents() {
        return students;
    }

    public void setStudents(List<Students> students) {
        this.students = students;
    }


}

  1. Students_Courses.java
 package com.caidi.beans;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name="students_courses")
public class Students_Courses {


    private String id;

    @Column(name="sid")
    private String sid;

    @Column(name="cid")
    private String cid;

    public Students_Courses() {
        super();
    }
    @Id
    @GeneratedValue(generator="system-uuid")  
    @GenericGenerator(name="system-uuid", strategy = "uuid.hex") 
    @Column(name="id")
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

}

  1. 测试代码
package com.caidi.Test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.caidi.beans.Courses;
import com.caidi.beans.Students;
import com.caidi.utils.HibernateTools;


public class TestManyToManyEach {
    @Test
    public void test01(){
        Session session = HibernateTools.getSession();
        //开启事物
        Transaction tr = session.beginTransaction();


        try{

            Courses c1 = new Courses();Courses c2 = new Courses();

            c1.setCname("数学课");

            c2.setCname("语文课");
            List list1 = new ArrayList();
            list1.add(c1);list1.add(c2);

            Students s1 = new Students();

            s1.setSname("小明");
            s1.setCourses(list1);

            session.save(s1);
            tr.commit();
            System.out.println("finsh");
            }catch(Exception e){
                tr.rollback();
                e.printStackTrace();
            }finally{
                if(session.isOpen() ==true){
                    session.close();
                }
            }
    }


}

mysql数据库
课程表courses

学生表students

中间表students_courses

5个回答

 原因:当使用bookid当主键的时候 使用Hibernate 并且将其实体映射 <generator class="native" /> 设为自动增长时会报此异常,因为uuid为字符型的无法使用数字型的自动增长。

解决方法:只需要将<generator class="native" /> 在实体中删除掉 问题即可解决。

个人感觉是中间表的id值生成出错,所以将Students_Courses.java的主键生成策略改为javax的auto,mysql数据库的中间表的id字段的类型改为 int并且自增,
结果,就保存正常了,我对此感到不解为什么students和courses的主键值就能有hibernate uuid自动生成,而中间表就不行,而且中间表主键类型改为int auto_increment
后,保存就正常了?

改动后的Students_Courses.java

 package com.caidi.beans;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name="students_courses")
public class Students_Courses {


    private int id;

    @Column(name="sid")
    private String sid;

    @Column(name="cid")
    private String cid;

    public Students_Courses() {
        super();
    }
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    //@GeneratedValue(generator="system-uuid")  
    //@GenericGenerator(name="system-uuid", strategy = "uuid.hex") 
    @Column(name="id")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

}

成功保存

 log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: 
    insert 
    into
        students
        (sname, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        courses
        (cname, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        courses
        (cname, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        students_courses
        (sid, cid) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        students_courses
        (sid, cid) 
    values
        (?, ?)
finsh

程序无法理解,有许多漏洞,需要修改!

看看配置数据库连接文件中的主键生成方式

看异常的出现关联的主键不存在,应该是你在创建关联id时候还没有保存到数据库,需要在servce里面添加事务,应该能解决问题。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问