我是JPA的新手。我在我的类上定义OneToOne双向流时遇到了麻烦。
UserInfo.java:
@Entity
@Table(name="UserInfo")
public class UserInfo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer idUserInfo;
private String firstName;
private String lastName;
@OneToOne(mappedBy="UserInfo")
private LoginInfo loginInfo;
LoginInfo.java:
@Entity
@Table(name="LoginInfo")
public class LoginInfo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer idLoginInfo;
@Column(name="emailId")
private String emailId;
//bidirectional one to one association to UserInfo
@OneToOne
@JoinColumn(name="emailId", referencedColumnName="loginInfo")
private UserInfo userInfo;
private String sessionId;
private String password;
这是创建这些表的SQL:
CREATE TABLE `LoginInfo` (
`emailId` varchar(45) NOT NULL,
`idLoginInfo` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`idLoginInfo`),
UNIQUE KEY `emailId_UNIQUE` (`emailId`),
UNIQUE KEY `id_UNIQUE` (`idLoginInfo`)
);
DROP TABLE IF EXISTS `UserInfo`;
CREATE TABLE `UserInfo` (
`idUserInfo` int(11) NOT NULL AUTO_INCREMENT,
`firstName` varchar(45) NOT NULL,
`lastName` varchar(45) NOT NULL,
`loginInfo` varchar(45) NOT NULL,
PRIMARY KEY (`idUserInfo`),
UNIQUE KEY `idUserInfo_UNIQUE` (`idUserInfo`),
UNIQUE KEY `loginInfo_UNIQUE` (`loginInfo`),
CONSTRAINT `loginInfo` FOREIGN KEY (`loginInfo`) REFERENCES `LoginInfo` (`emailId`) ON DELETE CASCADE ON UPDATE CASCADE
);
当我启动Tomcat服务器时,我在ContextInitialization上获得了以下异常。
Caused by: org.hibernate.MappingException: Unable to find column with logical name: loginInfo in org.hibernate.mapping.Table(UserInfo) and its related supertables and secondary tables
但该列确实存在于UserInfo表中。如果映射是正确的,有人可以帮助我吗?
由于
答案 0 :(得分:2)
无效关联: @JoinColumn(名称=" emailId",referencedColumnName =" loginInfo")
@Entity
@Table(name="UserInfo")
public class UserInfo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer idUserInfo;
private String firstName;
private String lastName;
@OneToOne(mappedBy = "userInfo", cascade = CascadeType.ALL)
private LoginInfo loginInfo;
@Entity
@Table(name="LoginInfo")
public class LoginInfo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer idLoginInfo;
@Column(name="emailId")
private String emailId;
//bidirectional one to one association to UserInfo
@OneToOne
@PrimaryKeyJoinColumn
private UserInfo userInfo;
private String sessionId;
private String password;
答案 1 :(得分:1)
阅读有关OneToOne映射,注释和一些试验&错误,我能够成功使用LoginInfo和UserInfo表。在我上面的问题中,它有一些无效的映射。要求是UserInfo是所有者实体,LoginInfo是子实体。因此,正如ashokhein所建议的那样,我使用了PrimaryKeyJoinColumn注释。这就是我的表格现在的样子。
CREATE TABLE `login_info` (
`user_info_id` bigint(100) NOT NULL,
`email_id` varchar(45) NOT NULL,
PRIMARY KEY (`user_info_id`),
UNIQUE KEY `email_id_UNIQUE` (`email_id`),
UNIQUE KEY `user_info_id_UNIQUE` (`user_info_id`),
CONSTRAINT `FK_login_info_user_info` FOREIGN KEY (`user_info_id`) REFERENCES `user_info` (`user_info_id`) ON DELETE CASCADE ON UPDATE CASCADE);
CREATE TABLE `user_info` (
`user_info_id` bigint(100) NOT NULL AUTO_INCREMENT,
`first_name` varchar(50) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`user_info_id`),
UNIQUE KEY `user_info_id_UNIQUE` (`user_info_id`));
这就是我的课程的样子:
的UserInfo:
@Entity
@Table(name = "user_info")
public class UserInfo {
@Id
@Column(name = "user_info_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer userId;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private LoginInfo loginInfo;
//Getters and setters
LoginInfo类:
@Entity
@Table(name = "login_info")
public class LoginInfo {
@Id
@Column(name = "user_info_id")
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "userInfo"))
private Integer id;
@OneToOne
@PrimaryKeyJoinColumn
private UserInfo userInfo;
@Column(name = "email_id")
private String emailId;
//Getters and setters
这就是我创建实体并将其保存到表中的方式:
UserInfo userInfo = new UserInfo();
userInfo.setFirstName(registerUserRequest.getFirstName());
userInfo.setLastName(registerUserRequest.getLastName());
LoginInfo loginInfo = userInfo.getLoginInfo();
if(loginInfo == null) {
loginInfo = new LoginInfo();
}
loginInfo.setEmailId(registerUserRequest.getEmailId());
loginInfo.setUserInfo(userInfo);
userInfo.setLoginInfo(loginInfo);
if(userService.create(userInfo)) {
logger.debug("User created successfully");
} else {
throw new UserAlreadyExistException();
}
在获得此解决方案的过程中,我遇到了大量的hibernate异常和问题。这里有一些(如果有人帮助的话)
Error: identifier of an instance of was altered from 14 to 14
解决方案:Entity类中的主键最初使用不同的类型。 user_info_id列在UserInfo中声明为Integer,在LoginInfo中声明为long。
Error: attempted to assign id from null one-to-one property
解决方案:在创建UserInfo对象时,我做了" userInfo.setLoginInfo(loginInfo)"但没有设置" loginInfo.setUserInfo(userInfo)"。修好后,很好。
Note: If you see a better way to do the same, please do comment here and let me know. Thanks in advance.