电子贺卡:
@Entity
@Table (name = "ecard")
public class Ecard {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@OneToOne (cascade = CascadeType.ALL)
@JoinColumn(name = "IdUser", nullable = false)
private User user;
@ManyToOne
@JoinColumn(name = "IdBank", nullable = false)
private Bank bank;
@Column (name = "accountNumber", nullable = false)
private int accountNumber;
public ECard(User user, Bank bank, int accNumber) {
this.user = user;
this.bank = bank;
this.accountNumber = accNumber;
}
}
用户:
@Entity
@Table (name="user")
public class User {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@OneToOne (mappedBy = "user")
private ECard eCard;
@ManyToOne
@JoinTable(
name = "ecard",
inverseJoinColumns = @JoinColumn(name = "IdBank", referencedColumnName = "Id"),
joinColumns = @JoinColumn(name = "IdUser", referencedColumnName = "Id")
)
private Bank bank;
public void seteCard(ECard eCard) {
this.eCard = eCard;
}
public void setBank(Bank bank) {
this.bank = bank;
}
}
行:
@Entity
@Table (name = "bank")
public class Bank {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(name = "name", nullable = false, unique = true)
private String name;
}
我已经初始化了Bank表,我想插入新用户,并将新的ECard链接到已存在于数据库中的Bank
我是新手,所以我无法理解为什么
我的代码不起作用:
//I checked and variable bank is okay, it's method argument
eManager.getTransaction().begin();
User user = new User();
ECard eCard = new ECard(user, bank, 1000);
user.seteCard(eCard);
user.setBank(bank); // PROBLEM
eManager.persist(eCard);
eManager.getTransaction().commit();
我得到了一个回滚例外:
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Field 'accountNumber' doesn't have a default value
Error Code: 1364
Call: INSERT INTO ecard (IdBank, IdUser) VALUES (?, ?)
bind => [2 parameters bound]
Query: DataModifyQuery(name="bank" sql="INSERT INTO ecard (IdBank, IdUser) VALUES (?, ?)")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:895)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:957)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:630)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:296)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelectCall(DatasourceCallQueryMechanism.java:271)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelect(DatasourceCallQueryMechanism.java:251)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.executeNoSelect(StatementQueryMechanism.java:118)
at org.eclipse.persistence.queries.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:85)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2894)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
at org.eclipse.persistence.mappings.OneToOneMapping.performDataModificationEvent(OneToOneMapping.java:2181)
at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:159)
at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4200)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1439)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1529)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1167)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
... 10 more
Caused by: java.sql.SQLException: Field 'accountNumber' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794)
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:885)
... 34 more
Java Result: 1
当我删除第user.setBank(bank)
行时效果很好,但我需要在用户银行中引用,所以删除这一行对我来说并不是那么好。
当我为accountNumber设置默认值时,我在eCard表中获得两行,一个是常规行,第二行是默认accountNumber,同样是IdUser和IdBank
如何避免该异常以及如何在Bank ??
上设置引用答案 0 :(得分:0)
您已经通过添加此
将ecard
声明为您的映射表
@ManyToOne
@JoinTable(
name = "ecard",
inverseJoinColumns = @JoinColumn(name = "IdBank", referencedColumnName = "Id"),
joinColumns = @JoinColumn(name = "IdUser", referencedColumnName = "Id")
)
但ecard
也用作实体,通过关联bankId和userId以及accountNumber字段来映射用户和银行的信息。
这就是为什么Jpa在用户的持久性中添加2条记录的原因 - 一条用于用户类name = 'ecard'
映射中的已定义映射,另一条用于ECard eCard = new ECard(user, bank, 1000);
我建议你将accountNumber字段移到银行类并删除ecard
类,因为JoinColumn (name = 'ecard'...
中的映射已经假定存在一个只有2列userId和bankId的表ecard
并且会处理它以默认方式。
或者删除用户类中的银行字段,因为用户已经引用了引用ecard
的{{1}}。但是现在您必须手动管理银行和用户之间的关联它在上面的代码中。