0

So I'm trying to create a class called Author and a class called Book. Each Book is associated with an Author. So I have the table schemas below:

CREATE TABLE author (
author_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(30),
email VARCHAR(50),

PRIMARY KEY(author_id)
);

and

CREATE TABLE book (
book_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(30),
description VARCHAR(50),
publish_date DATE,
author_id BIGINT UNSIGNED NOT NULL,

PRIMARY KEY(book_id),
FOREIGN KEY(author_id) REFERENCES author(author_id)
);

Here are the associated classes:

@Entity
@Table(name="Author")
public class Author {

    @Id
    @GeneratedValue
    @Column(name="AUTHOR_ID")
    private long id;

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

    @Column(name="EMAIL")
    private String email;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<Book> books;

    //Getters and setters below...

and

@Entity
@Table(name="Book")
public class Book {

    @Id
    @GeneratedValue
    @Column(name="BOOK_ID")
    private long id;

    @Column(name="TITLE")
    private String title;

    @Column(name="DESCRIPTION")
    private String description;

    @Column(name="PUBLISH_DATE")
    private Date publishDate;

    @ManyToOne
    @JoinColumn(name="AUTHOR_ID")
    private Author author;

    //Getters and setters below...

Whenever I attempt to create a SessionFactory and save/update/delete data, it seems I MUST have a table called Author_Book. If I let Hibernate create the table schemas, it automatically creates them. However, if I have create turned off, it says that it cannot find the table Author_Book but I don't want that table because it seems unnecessary. Also, if it creates Author_Book I cannot delete anything from Author or Book because it says there's a foreign key association in the table Author_Book.

How can I stop Hibernate from generating these table1_table2 schemas. If there is no way to stop it, or if this table is important for some reason, how can I delete/update info without Hibernate saying there's a foreign key relationship in the Author_Book table?

EDIT: The error comes when I try to do transaction.commit(). I get the following stack trace:

Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute statement
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:80)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
    at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1311)
    at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:67)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:453)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:345)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1218)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:421)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
    at main.Test.main(Test.java:46)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'author1234.author_book' doesn't exist
    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:406)
    at com.mysql.jdbc.Util.getInstance(Util.java:381)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2643)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2362)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2280)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2265)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)
Jake Miller
  • 2,432
  • 2
  • 24
  • 39
  • Your mapping is wrong. You want a bidirectional association, but you created two separate unidirectional associations. Read the manual: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations-one-to-many-bidirectional – JB Nizet Jun 21 '16 at 20:45
  • @JBNizet you didn't even read my post entirely... I was asking what's the point of Hibernate creating the table `Author_Book` and how to disable that feature. My mapping is fine. My code works perfectly if I allow Hibernate to create the table schemas. Please read the ENTIRE question before answering. – Jake Miller Jun 21 '16 at 21:16
  • It creates this table because you asked for a unidirectional OneToMany mapping, and the default for such a mapping is to use a join table. Create a **bidirectional** association instead, as explained in the documentation I linked to, and in the duplicate question, and Hibernate won't create that table anymore. Your mapping **is** wrong. And the fact that Hibernate creates that table **proves** it. Don't ask questions if you don't trust the answers you get. I read your question. But you didn't read the answer. – JB Nizet Jun 21 '16 at 21:21
  • 1
    @JBNizet Ahh. I apologize for being passive aggressive and really do appreciate the help. This solved my issue. – Jake Miller Jun 21 '16 at 21:30

0 Answers0