0
我有這些實體要與雙向關聯。JPA:「無法寫入表中的重複鍵」以獲得一對一關係
憑據:
@Entity
@Access(AccessType.PROPERTY)
@Table(name = "credential")
public class Credential extends MetaInfo implements Serializable {
...
private Email email;
...
@OneToOne(cascade = CascadeType.ALL, optional = false, orphanRemoval = true)
@JoinColumn(name="email", referencedColumnName="email_address")
public Email getEmail() {
return email;
}
public void setEmail(Email email) {
this.email = email;
}
...
}
電子郵件:
@Entity
@Access(AccessType.PROPERTY)
@Table(name = "email")
public class Email extends MetaInfo implements Serializable{
...
private Credential credential;
public Email() {
}
public Email(String emailAddress) {
this.emailAddress = emailAddress;
}
@Id
@Column(name="email_address")
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
@OneToOne(mappedBy = "email", optional=false)
public Credential getCredential() {
return credential;
}
public void setCredential(Credential credential) {
this.credential = credential;
}
}
在CredentialRepository
類我測試是否傳入的電子郵件 沒有分配到任何用戶除了與通過用戶名的用戶-in作爲第二個(可選)參數:
@Override
public boolean emailIsAssigned(String... args) {
assert(args.length > 0);
if(InputValidators.isValidEmail.test(args[0])){
EntityManager em = entityManagerFactory.createEntityManager();
try {
TypedQuery<Long> count = em.createQuery("SELECT COUNT(e) "
+ "FROM Email e WHERE e.emailAddress "
+ "= :email AND e "
+ "IN (SELECT c.email FROM Credential c WHERE c.username "
+ "!= :username)", Long.TYPE).setParameter("email", args[0])
.setParameter("username", null);
if(InputValidators.stringNotNullNorEmpty.apply(args[1])){
//only if the username has been provided
count.setParameter("username", args[1]);
}
return count.getSingleResult() > 0;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
} finally {
em.close();
}
}else{
throw new NotAValidEmailException(args[0] + " is not a"
+ " valid email address.");
}
}
因此,上面的args[0]
是被測試的電子郵件,args[1]
是被測試的用戶名。
這是導致我的問題(注意,之前我已經試驗成功插入,更新,甚至emailIsAssigned
方法,但測試沒有這似乎使問題c.email
部分:
@Test
public void emailAlreadyExistsTest(){
assertTrue(credentialRepo.emailIsAssigned("[email protected]"));
}
而且這是錯誤信息,我有:
[EL Warning]: 2017-04-17 17:55:33.606--ServerSession(234430897)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Can't write; duplicate key in table '#sql-3e4_9a'
Error Code: 1022
Call: ALTER TABLE credential ADD CONSTRAINT FK_credential_email FOREIGN KEY (email) REFERENCES email (email_address)
Query: DataModifyQuery(sql="ALTER TABLE credential ADD CONSTRAINT FK_credential_email FOREIGN KEY (email) REFERENCES email (email_address)")
我將不勝感激,如果有人能夠給我一個忠告,我總是可以只改變電子郵件爲String和其標記爲「獨一無二」。,但我覺得沒有理由選擇的方法不工作。
我使用MySQL作爲數據庫供應商和Eclipse-Link JPA實現。我確實試圖「硬化」FK約束的名稱,但無濟於事。數據庫和所有表具有相同的排序規則(utf8_unicode_ci)。
恐怕這是不可能的。刪除'@ Id'註釋會使.java文件不可編譯。除了MetaInfo只是一個抽象類('@ MappedSuperclass') - 它本身沒有主鍵。 – vasigorc