2012-07-31 67 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