2 つのエンティティ間の 1 対 1 のマッピングを正常に作成しました。2 つのテーブルからデータを取得できますが、挿入を実行できません。
@Entity
@Table(name="users_test")
public class User {
@Id
@Column(name="user_id")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String username;
private String password;
private int enabled;
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private UserRole userRole;
//getters and setters
}
@Entity
@Table(name = "user_roles")
public class UserRole {
private int user_role_id;
@Id
@GeneratedValue(generator = "gen")
@Column(name = "user_id", unique = true, nullable = false)
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="user"))
private int user_id;
private String authority;
@OneToOne(mappedBy="userRole", cascade=CascadeType.ALL)
private User user;
//getters and setters
}
このマッピングを介してテーブルから値を読み取ることができましたが、テーブルにデータを挿入しようとするとエラーが発生します。
public class Runner {
public static void main(String[] args) {
Runner run = new Runner();
ApplicationContext context = new FileSystemXmlApplicationContext("E:\\applicationContext.xml");
UserDao userDao = (UserDao) context.getBean("userDao");
UserRole userRole = new UserRole();
userRole.setAuthority("USER_ROLE");
userRole.setUser_role_id(0);
User user = new User();
user.setUsername("ichigo");
user.setPassword("kura");
user.setEnabled(0);
user.setUserRole(userRole);
userDao.insertUser(user);
}
}
ユーザーダオ:
@SuppressWarnings("unchecked")
@Repository
@Transactional
public class UserDao {
@Autowired
SessionFactory sessionFactory;
public List<User> getUsers() {
Session currentSession = sessionFactory.getCurrentSession();
return currentSession.createQuery("from User").list();
}
public void insertUser(User user) {
sessionFactory.getCurrentSession().save(user);
}
}
次の例外が発生します。
Exception in thread "main" org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [test.hibernate.model.UserRole.user]
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:101)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:118)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:114)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:724)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:716)
at org.hibernate.engine.spi.CascadingAction$5.cascade(CascadingAction.java:258)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:448)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:293)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:753)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:745)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:741)
at test.hibernate.dao.UserDao.insertUser(UserDao.java:24)
at test.hibernate.dao.UserDao$$FastClassByCGLIB$$192f03a.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at test.hibernate.dao.UserDao$$EnhancerByCGLIB$$7428e072.insertUser(<generated>)
at test.hibernate.test.main.Runner.main(Runner.java:34)
私が間違っていることについてアドバイスをください。
編集:
返信から、コード内で外部キーが混同されているようです。質問を明確にしてください。テーブルのスキーマを投稿しています。
CREATE TABLE `users_test` (
`USER_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`USERNAME` varchar(45) NOT NULL,
`PASSWORD` varchar(45) NOT NULL,
`ENABLED` tinyint(1) NOT NULL,
PRIMARY KEY (`USER_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=113 DEFAULT CHARSET=utf8
CREATE TABLE `user_roles` (
`USER_ROLE_ID` int(10) DEFAULT NULL,
`USER_ID` int(10) unsigned NOT NULL,
`AUTHORITY` varchar(45) NOT NULL,
PRIMARY KEY (`USER_ID`),
KEY `FK_user_roles` (`USER_ID`),
CONSTRAINT `FK_user_roles` FOREIGN KEY (`USER_ID`) REFERENCES `users_test` (`USER_ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8