2012-07-31 69 views
2

嗨我想做一到多插入,但我有問題。 我有兩個表:一對多冬眠

CREATE TABLE users_app (
    user_id int UNSIGNED NOT NULL AUTO_INCREMENT, 
    user_number varchar(45) NOT NULL default '0', 
    user_password varchar(45) NOT NULL default '0', 
    os int(1) unsigned NOT NULL, 
    token varchar(500) NOT NULL, 
    PRIMARY KEY (`user_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8; 

CREATE TABLE user_app_devices( 
    id int AUTO_INCREMENT PRIMARY KEY, 
    user_id int UNSIGNED NOT NULL, 
    device_name varchar(45) NOT NULL, 
    FOREIGN KEY (user_id) REFERENCES users_app (user_id) 
)ENGINE=InnoDB CHARSET=utf8; 

我的課:

@Entity 
@Table(name="user_app_devices") 
public class UserAppDevice implements Serializable { 
private static final long serialVersionUID = 1L; 

@Id 
private int id; 

@Column(name="device_name") 
private String deviceName; 

//bi-directional many-to-one association to UsersApp 
@ManyToOne 
@JoinColumn(name="user_id") 
private UsersApp usersApp; 

public UserAppDevice() { 
} 

public int getId() { 
    return this.id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public String getDeviceName() { 
    return this.deviceName; 
} 

public void setDeviceName(String deviceName) { 
    this.deviceName = deviceName; 
} 

public UsersApp getUsersApp() { 
    return this.usersApp; 
} 

public void setUsersApp(UsersApp usersApp) { 
    this.usersApp = usersApp; 
} 

} 

@Entity 
@Table(name="users_app") 
public class UsersApp implements Serializable { 
private static final long serialVersionUID = 1L; 

@Id 
@Column(name="user_id") 
private int userId; 

private int os; 

private String token; 

@Column(name="user_number") 
private String userNumber; 

@Column(name="user_password") 
private String userPassword; 

//bi-directional many-to-one association to UserAppDevice 
@OneToMany(mappedBy="usersApp") 
private List<UserAppDevice> userAppDevices; 

public UsersApp() { 
} 

public int getUserId() { 
    return this.userId; 
} 

public void setUserId(int userId) { 
    this.userId = userId; 
} 

public int getOs() { 
    return this.os; 
} 

public void setOs(int os) { 
    this.os = os; 
} 

public String getToken() { 
    return this.token; 
} 

public void setToken(String token) { 
    this.token = token; 
} 

public String getUserNumber() { 
    return this.userNumber; 
} 

public void setUserNumber(String userNumber) { 
    this.userNumber = userNumber; 
} 

public String getUserPassword() { 
    return this.userPassword; 
} 

public void setUserPassword(String userPassword) { 
    this.userPassword = userPassword; 
} 

public List<UserAppDevice> getUserAppDevices() { 
    return this.userAppDevices; 
} 

public void setUserAppDevices(List<UserAppDevice> userAppDevices) { 
    this.userAppDevices = userAppDevices; 
} 

public UsersApp(int os, String token, String userNumber, String userPassword) { 
    this.os = os; 
    this.token = token; 
    this.userNumber = userNumber; 
    this.userPassword = userPassword; 
} 

我要添加新的用戶與設備

我試試這個代碼:

Session session = (Session) em.getDelegate(); 
    session.beginTransaction(); 

    UsersApp user = new UsersApp(os, token, userNumber, userPassword); 

    session.save(user); 

    UserAppDevice ud = new UserAppDevice(); 

    ud.setUsersApp(user); 
    ud.setDeviceName(device); 

    session.save(ud); 

    session.getTransaction().commit(); 

但我面臨例外:

13:16:48,516 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--0.0.0.0-8080-3) SQL Error: 1452, SQLState: 23000 
13:16:48,517 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--0.0.0.0-8080-3) Cannot add or update a child row: a foreign key constraint fails (`application`.`user_a 
pp_devices`, CONSTRAINT `user_app_devices_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_app` (`user_id`)) 
13:16:48,520 ERROR [org.jboss.as.ejb3.tx.CMTTxInterceptor] (http--0.0.0.0-8080-3) javax.ejb.EJBTransactionRolledbackException: Cannot add or update a child row: a foreign key const 
raint fails (`application`.`user_app_devices`, CONSTRAINT `user_app_devices_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_app` (`user_id`)) 
13:16:48,524 ERROR [org.jboss.ejb3.invocation] (http--0.0.0.0-8080-3) JBAS014134: EJB Invocation failed on component DeviceRegisterDAOImpl for method public abstract void com.break 
id.ejb.model.DeviceRegisterDAO.add(int,java.lang.String,java.lang.String,java.lang.String,java.lang.String): javax.ejb.EJBTransactionRolledbackException: Cannot add or update a chi 
ld row: a foreign key constraint fails (`application`.`user_app_devices`, CONSTRAINT `user_app_devices_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_app` (`user_id`)) 
     at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:139) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] 
     at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:204) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] 
     at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:306) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] 
     at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] 
     at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final] 
     at org.jboss.as.ejb3.remote.EJBRemoteTransactionPropagatingInterceptor.processInvocation(EJBRemoteTransactionPropagatingInterceptor.java:80) [jboss-as-ejb3-7.1.1.Final.jar: 
7.1.1.Final] 

我錯過了什麼?

回答

1

你還沒告訴,是由數據庫自動生成UserApp的ID休眠:由於您使用的是雙向的,變化

@Id 
@GeneratedValue(strategy = IDENTITY) 
@Column(name="user_id") 
private int userId; 

(和其他實體做相同)

+0

它worked.Thanks – Breakidi 2012-07-31 11:36:49

0

您的客戶代碼如下。

Session session = (Session) em.getDelegate(); 
session.beginTransaction(); 
UserAppDevice ud = new UserAppDevice(); 
ud.setDeviceName(device); 
UsersApp user = new UsersApp(os, token, userNumber, userPassword); 
user.setUserAppDevices(new ArrayList<UserAppDevice>()) 
user.getUserAppDevices().add(ud); 
session.save(user); 
session.getTransaction().commit(); 
+0

這並沒有工作, 只有用戶添加到數據庫,設備沒有 – Breakidi 2012-07-31 11:45:02

0

正如JB Nizet提到的,你錯過了自動生成的策略。

另一種方法是使用UUID爲您id柱和自己與

@Id 
private UUID id = UUID.randomUUID(); 

同時創建值,如The JPA hashCode()/equals() dilemma

討論到死都不忘記設置 equals/hashCode使用 id

順便說一下,爲什麼你使用Session(特定於hibernate)而不是堅持JPA的API?

+0

的OP具有的mappedBy屬性,它在每個雙向關聯強制性的,是否使用一個連接表或使用連接列。關於equals/hashCode:它們不是強制性的,Hibernate建議不要使用ID。 – 2012-07-31 10:51:12

+0

你太遲了:-P我真的發現了這一點,並在7分鐘前更新了我的評論。我沒有在代碼片段上看到滾動條,我最初並沒有看到第二個'class'定義。我知道Hibernate推薦了一個商業密鑰,但是這個論點是舊帽子 - 現代約定是使用'id'並且在構建時自己生成密鑰。我使用'UUID',因爲它避免了必須使用奇怪的系統來確保數據庫中的唯一性。 – fommil 2012-07-31 10:56:38

+0

這只是在你的地方現代。 UUID的效率低於PK的數字,並且序列或auto_increment比UUID更易於使用。 – 2012-07-31 11:16:15