[英]Hibernate One-To-One relationship
I see many turoials and articles about subject, but i can't understand one thing. 我看到许多有关主题的语言和文章,但我无法理解一件事。 For a example: i have "User" table with fields "id", "name" and i have "UserBanned" table with fields "userid" and "reason".
例如:我有“用户”表,字段为“id”,“name”,我有“UserBanned”表,字段为“userid”和“reason”。 UserBanned.userid - it is link (foreign key) on field User.id.
UserBanned.userid - 它是字段User.id上的链接(外键)。
So, models in hiberante looks like: 因此,hiberante中的模型看起来像:
@Entity
@Table(name = "user")
@DynamicInsert
public class User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "user_id_generator")
@SequenceGenerator(name = "user_id_generator", sequenceName = "user_id_seq")
protected Integer id;
@Column
protected Integer name;
@OneToOne (mappedBy = "user", cascade = CascadeType.ALL)
protected UserBanned userBanned;
And UserBanned model: 和UserBanned模型:
@Entity
@Table(name = "userbanned")
@DynamicInsert
public class UserBanned{
@Id
@Column(name="userid", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="user"))
protected Integer userid;
@Column
protected String reason;
@OneToOne
@PrimaryKeyJoinColumn
protected User user;
And it works. 它有效。 I can create new user and banned user with this code:
我可以使用以下代码创建新用户和禁止用户:
User user = new User();
user.setName(name);
UserBanned userBanned = new UserBanned ();
userBanned.setReason(reason);
user.setUserBanned(userBanned );
userBanned.setUser(user);
clientService.store(user);
But, when i try to do gson.toJson(client) i got stackoverflow error - because Gson can't handle circular references in the serialized data. 但是,当我尝试做gson.toJson(客户端)时,我得到了stackoverflow错误 - 因为Gson无法处理序列化数据中的循环引用。 But my mind cant understand why i have to set User in UserBanned?!
但我的想法无法理解为什么我必须在UserBanned中设置用户?! Why i can not just have model User?
为什么我不能只拥有模特用户?
My question: how i can organize such relationship (One-To-One with foreign key) like User (there are not only UserBanned, but and UserVIP and etc entities) in hibernate? 我的问题:如何在hibernate中组织这样的关系(一对一与外键),如User(不仅有UserBanned,还有UserVIP和其他实体)?
You should exclude one of cycled references ( User::userBanned
or UserBanned::user
) from serialization and deserialization by Gson
. 您应该从
Gson
序列化和反序列化中排除一个循环引用( User::userBanned
或UserBanned::user
)。
You can read about it in gson-documentation . 你可以在gson文档中阅读它。
Add some annotation 添加一些注释
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Exlude
{
}
Create ExclusionStrategy 创建ExclusionStrategy
public class MyExclusionStrategy implements ExclusionStrategy
{
public boolean shouldSkipClass(Class<?> clazz)
{
return false;
}
public boolean shouldSkipField(FieldAttributes f)
{
return f.getAnnotation(Exlude.class) != null;
}
}
Create Gson
instance with GsonBuilder
使用
GsonBuilder
创建Gson
实例
Gson gson = new GsonBuilder()
.setExclusionStrategies(new MyExclusionStrategy())
.create();
Annotate UserBanned::user
with @Exclude
annotation 使用
@Exclude
批注对UserBanned::user
进行批注
@OneToOne
@PrimaryKeyJoinColumn
@Exclude
protected User user;
If you don't want UserBanned
to have reference to User
, you could make the UserBanned
embeddable and embed it in User
. 如果您不希望
UserBanned
引用User
,您可以将UserBanned
嵌入并嵌入User
。
@Embeddable
public class UserBanned{
....
}
@Entity
@Table(name = "user")
@DynamicInsert
public class User{
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "user_id_generator")
@SequenceGenerator(name = "user_id_generator", sequenceName = "user_id_seq")
protected Integer id;
@Column
protected Integer name;
@Embedded
protected UserBanned userBanned;
If you want the UserBanned
to be in separate database-table and the table should contain reference to the user
-table, I don't think you can avoid having the User
in UserBanned
, otherwise Hibernate won't know which User
the UserBanned
refers to. 如果你想让
UserBanned
在单独的数据库表中并且表应该包含对user
表的引用,我认为你不能避免在UserBanned
中使用User
,否则Hibernate将不知道UserBanned
引用哪个User
。
If you want just to get rid of the line userBanned.setUser(user);
如果你想要摆脱
userBanned.setUser(user);
, you could set the User
to UserBanned
in Users
setUserBanned(userBanned );
,你可以设置
User
到UserBanned
在Users
setUserBanned(userBanned );
-method. -方法。
public void setUserBanned(UserBanned userBanned) {
this.userBanned = userBanned;
userBanned.user(this);
}
And then excluding the field from serialization for example in way suggested in Ilyas answer . 然后从序列化中排除字段,例如在Ilyas答案中建议的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.