【问题标题】:Eclipselink JPA ManyToOne mapping issueEclipselink JPA 多对一映射问题
【发布时间】:2014-09-19 03:46:58
【问题描述】:

我是 JPA(eclipselink)的新手,我正在尝试使用 ManyToOne unidirectional mapping,我有 superclass Studentsubclass Book,当我尝试保存对象时,我最终会遇到异常,详细信息如下所示

学生是父类

@Entity
@Table(name="STUDENT")
@TableGenerator(name="student_s", initialValue=1)
public class Student {
    @Id 
    @Column(name="student_id")
    @GeneratedValue(strategy=GenerationType.TABLE ,generator="student_s")
    private int studentID;

    @Column(name="full_name",nullable=false)
    private String student_name;

    public int getStudentID() {
        return studentID;
    }

    public void setStudentID(int studentID) {
        this.studentID = studentID;
    }

    public String getStudent_name() {
        return student_name;
    }

    public void setStudent_name(String student_name) {
        this.student_name = student_name;
    }

}

Book 是子类

@Entity
@Table(name="BOOK")
@TableGenerator(name="book_s", initialValue=1)
public class Book {
    @Id 
    @Column(name="book_id")
    @GeneratedValue(strategy=GenerationType.TABLE ,generator="book_s")
    private int bookID;

    @Column(name="book_name")
    private String bookName;

    @Column(name="student_id")
    private String studentID;

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="student_id",referencedColumnName="student_id",insertable=false,updatable=false)
    private Student student;

    public int getBookID() {
        return bookID;
    }

    public void setBookID(int bookID) {
        this.bookID = bookID;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getStudentID() {
        return studentID;
    }

    public void setStudentID(String studentID) {
        this.studentID = studentID;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }


}

执行persist操作的主类,执行persist时抛出未知列异常。

public class Main {
    public static void main(String args[]){     
        Student student = new Student();
        student.setStudent_name("Prem");

        Book book = new Book();
        book.setBookName("The Best Laid Plan");
        book.setStudent(student);

        EntityManagerFactory emf=Persistence.createEntityManagerFactory("premjpaeclipselink");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.persist(book);
        em.getTransaction().commit();
        em.close();
        emf.close();
    }
}

例外:

]: sql: Connection(635083092)--INSERT INTO BOOK (book_id, book_name, student_id) VALUES (?, ?, ?)
    bind => [351, The Best Laid Plan, null]
[EL Fine]: sql: SELECT 1
[EL Warning]: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'book_name' in 'field list'
Error Code: 1054
Call: INSERT INTO BOOK (book_id, book_name, student_id) VALUES (?, ?, ?)
    bind => [351, The Best Laid Plan, null]
Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'book_name' in 'field list'
Error Code: 1054
Call: INSERT INTO BOOK (book_id, book_name, student_id) VALUES (?, ?, ?)
    bind => [351, The Best Laid Plan, null]
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
    at org.prem.jpa.eclipselink.Main.main(Main.java:31)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'book_name' in 'field list'
Error Code: 1054
Call: INSERT INTO BOOK (book_id, book_name, student_id) VALUES (?, ?, ?)
    bind => [351, The Best Laid Plan, null]
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:900)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
    at org.eclipse.persistence.internal.databaseaccess.ParameterizedSQLBatchWritingMechanism.executeBatch(ParameterizedSQLBatchWritingMechanism.java:149)
    at org.eclipse.persistence.internal.databaseaccess.ParameterizedSQLBatchWritingMechanism.executeBatchedStatements(ParameterizedSQLBatchWritingMechanism.java:134)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.writesCompleted(DatabaseAccessor.java:1836)
    at org.eclipse.persistence.internal.sessions.AbstractSession.writesCompleted(AbstractSession.java:4244)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.writesCompleted(UnitOfWorkImpl.java:5594)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.acquireWriteLocks(UnitOfWorkImpl.java:1646)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitTransactionAfterWriteChanges(UnitOfWorkImpl.java:1614)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:284)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
    ... 1 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'book_name' in 'field list'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1053)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)
    ... 13 more

【问题讨论】:

    标签: java jpa eclipselink


    【解决方案1】:

    我可以从您的异常堆栈跟踪中看到这一行:

    Unknown column 'book_name' in 'field list'

    确保 BOOK 表中的“book_name”列在数据库中是正确的

    希望对你有帮助!!!

    【讨论】:

    • 是的,是列名的问题,异常消失了,但是学生id没有保存在书表中,student_id值为0,没有从父表Student中提取该值。
    • 您不需要 BOOK 表中的学生 ID,因为您在 BOOK 类中已经有学生对象引用了学生实体。使用JPA反向引擎工具(为您生成实体类)来避免此类问题。
    【解决方案2】:

    将 Book 类中的 private String studentID; 更改为 private int studentID; 并更改相应的 getter 和 setter。

    【讨论】:

    • 在数据库中检查 book_name 字段是否存在同名。并且建议您在数据库中没有已经存在的故事,并让 JPA 自己创建表。
    • 数据库中的列名错误,我修改了。
    【解决方案3】:

    实体运作良好。这是列名的问题。为了确保您的 DDL,您可以使用 with

    <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>.

    正如@Sanket Pipariya 所说,你不需要

    @Column(name="student_id")
    private String studentID;
    

    因为您已经有学生对象(Book 表中的“student_id”列)。 您在 Book Class 的 Student 属性中使用 insertable=false,这样当您将 Book 对象与 Student 属性一起持久化时,Book 表中的 student_id 列将为空。

    【讨论】:

      【解决方案4】:

      当您在书本和学生的数据库中创建表时,此异常将被删除。 然后将插入记录。

      【讨论】:

        猜你喜欢
        • 2020-11-30
        • 2021-02-21
        • 2011-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-27
        • 2015-07-02
        相关资源
        最近更新 更多