3
votes

Running my play framework small app I get the following exception:

... Caused by: java.sql.BatchUpdateException: Field 'sentTO_id' doesn't have a default value ...

The error play spits out in the browser is

PersistenceException occured : insert into Mail_User (Mail_id, sentBCC_id) values (?, ?)

i have 2 entities Mail and User

1) Mail.java

@Entity
public class Mail extends Model {


   public String title;

   public Date sentAt;
   @OneToMany
   public List<User> sentTO;
   @OneToMany
   public List<User> sentBCC;


    public String content;

    @ManyToOne
    public User author;

//more code ...
}

2) User.java

@Entity
public class User extends Model {

    public String email;
    public String password;
    public String fullname;
    public boolean isAdmin;

    @OneToMany(mappedBy="author", cascade= CascadeType.ALL)
    public List<Mail> mails ;

    public User(String email, String password, String fullname) {
        this.email = email;
        this.password = password;
        this.fullname = fullname;
    }

}

full stack

Internal Server Error (500) for request POST /mails/create

Execution exception (In {module:crud}/app/controllers/CRUD.java around line 152) PersistenceException occured : insert into Mail_User (Mail_id, sentBCC_id) values (?, ?)

play.exceptions.JavaExecutionException: insert into Mail_User (Mail_id, sentBCC_id) values (?, ?) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:231) at Invocation.HTTP Request(Play!) Caused by: javax.persistence.PersistenceException: insert into Mail_User (Mail_id, sentBCC_id) values (?, ?) at play.db.jpa.JPABase._save(JPABase.java:38) at controllers.CRUD.create(CRUD.java:152) at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:548) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:478) at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473) at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161) ... 1 more Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214) at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147) at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1153) at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:798) at play.db.jpa.JPABase._save(JPABase.java:35) ... 7 more Caused by: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140) at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114) at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109) at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244) at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1179) at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:345) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:795) ... 8 more Caused by: java.sql.BatchUpdateException: Field 'sentTO_id' doesn't have a default value at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2018) at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1449) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) ... 20 more

I've been scratching my head over this error for sometime now but can't work it out. Could someone help me understand why I am getting this error?

2

2 Answers

4
votes

First of all, sendTo and sendBCC should be mapped as @ManyToMany.

Secondly, by default undirectional @OneToMany mappings and all @ManyToMany mappings are implemented using join table, and default generation strategy for join table name doesn't allow you to have multiple such relationships between the same classes.

You need to specify join table names explicitly:

@ManyToMany
@JoinTable(name = "User_Mail_To")
public List<User> sentTO;

@ManyToMany
@JoinTable(name = "User_Mail_Bcc")
public List<User> sentBCC; 
3
votes

The error: "Field 'sentTO_id' doesn't have a default value" is probably caused by the fact that you changed your model but didn't recreate your DB.

sentTO_id is a required field in the old model.