懒惰的一对一春天JPA和建立“动态”的JSON [英] Lazy One-To-One Spring JPA and building "dynamic" JSON

查看:158
本文介绍了懒惰的一对一春天JPA和建立“动态”的JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring Boot开发一个相对较大的项目,一般来说我很满意它,但我遇到了一些问题,在我看来应该不是问题。

I'm developing a relatively large project using Spring Boot, and in a general way I'm pretty happy with it, but I'm having some problems that in my mind should't be a problem.


  1. 首先,一对一的关系。令人沮丧的是它不能正常工作(至少在我看来)。

  1. First of all, One-To-One Relationship. It's frustrating that it doesn't work as it should (at least in my mind).

我有两个实体,用户 UserProfile 。他们有一对一的关系,但大部分时间我只需要用户数据,但它取出(无论我尝试什么,哦,男孩,我试过关于5页Google的每篇文章的世界建议。)

I have two entities, User and UserProfile, for example. They have One-To-One relationship, but most of the time I only need the User data, but it fetches (no matter what I try, and oh boy, I tried the world suggestions on every post for 5 pages of Google).

所以我的第一个问题是,有没有办法可以懒得一对一JPA和Spring的关系? (因为大多数帖子都超过2 - 3年了。)

So there is my first question, is there a way to be able to lazy fetch One-To-One relationship in JPA and Spring? (Because most of the posts are more than 2-3 years old).

我遇到的另一个问题是在动态中构建JSON响应 办法。我使用Rails做了一些事情并且对 JBuilder 甚至 to_json 非常满意,这使我能够构建json响应取决于控制器和我目前的需求。

The other problem I have is about to build a JSON response in a "dynamic" way. I did some stuff using Rails and was very happy with JBuilder or even the to_json that gave me the ability to build the json response depending on the controller and my needs at the moment.

在Spring中我看到了以下解决方案:

In Spring I saw the following solutions:


  • Jackson @JsonView (这并不完全解决我的问题,因为响应不是静态的,并且属性不能分配给多个视图(据我理解的概念而言));

  • 设置为null我不想要的属性(使用它,但是我太丑了,看起来像个错误演练);

  • 或构建 HashMap 就像我构建 .json.jbuilder 在Rails上(但是这会影响我的表现,因为有时它会有很多来构建json,而且这看起来像是一个丑陋的演练)。

  • Jackson @JsonView (which doesn't solve entirely my problem because the responses are not that static and a attribute can't be assigned to multiple views (as far as I understood the concept));
  • setting to null attributes that I don't want on the response (using this, but I's just too ugly and looks like a wrong walkthrough);
  • or building HashMap like I build .json.jbuilder on Rails (but this kills my performance as sometimes it has relationships so a lot of for to build the json, and also this looks like a ugly walkthrough).

我正在寻找一些方向某人可能遇到其中一个问题,因为它让我无法解决问题,在我看来不应该这么难。

I'm looking for some directions from someone that someday may have encountered one of this problems because it's killing me not being able so solve problems that in my mind should not be this hard.

编辑1

已经尝试在 @OneToOne上添加 optional = false 注释解决了@snovelli建议的OneToOne关系的Eager负载。示例:

Already tried to add optional = false on the @OneToOne annotation to solve the Eager load of OneToOne relationship as @snovelli suggested. Example:

@OneToOne(optional=false, fetch = FetchType.LAZY)
public UserProfile getUserProfile(){ ... }


推荐答案

如果连接列不在一对一关联中的父级映射到的表,然后关联不能懒。原因是JPA提供程序无法确定是否创建代理,以便它可以在以后访问时加载对象,或保留 null 值。

If the join column is not in the table to which a parent in a one-to-one association is mapped, then the association cannot be lazy. The reason is that JPA provider cannot determine whether to create the proxy, so that it can load the object when accessed later, or leave the null value.

即使关联不是可选的,JPA提供者也必须确定关联实体实例的id以将其存储在代理中。因此,无论如何它必须转到相关的表格。

Even if the association is not optional, JPA provider has to determine the id of the associated entity instance to store it in the proxy. Thus it has to go to the associated table anyway.

解决方案:


  1. 字节代码检测。但是没有广泛采用的方法。

  2. 使用一对多并将空列表处理为 null ,否则使用 list.get(0)。您当然可以将其封装在实体类中(getter返回列表中唯一的元素或 null )。缺点是您必须将其视为JPQL查询中的集合。

  3. 使用 @PrimaryKeyJoinColumn 而不是外键。如果关联不是可选的( optional = false ),则JPA提供程序知道存在具有相同PK的关联子级,因此它将只存储父级的PK作为代理中孩子的id。显然,您不能为两个实体使用两个独立的id生成器,否则PK可能不同。如果它符合您的要求,这是最好的方法。

  4. 也在父表中添加外键(在数据库中也建立双向关系)。缺点是你现在基本上有两个独立的关联,你必须维护。此外,还有更新两个表而不是一个表的性能成本(并且外键必须可以为空)。

  5. 将父实体映射到连接父表的数据库视图使用子表并包含所有父列加上子表的id:

  1. Byte code instrumentation. Not widely adopted approach though.
  2. Use one-to-many and handle empty list as null, otherwise use list.get(0). You can of course encapsulate this in the entity class (getter returns the only element of the list or null). The drawback is that you will have to treat this as collection in JPQL queries.
  3. Use @PrimaryKeyJoinColumn instead of a foreign key. If the association is not optional (optional = false), then JPA provider knows that there is an associated child with the same PK, so it will just store the PK of the parent as the id of the child in the proxy. Obviously, you can't use two independent id generators for both of the entities, otherwise PKs may be different. This is the best approach if it meets your requirements.
  4. Add the foreign key in the parent table also (making the relationship bidirectional in the database as well). The drawback is that you now basically have two independent associations which you have to maintain. Also, there is the performance cost of updating two tables instead of one (and the foreign keys have to be nullable).
  5. Map parent entity to a database view that joins parent table with the child table and contains all parent columns plus id of child table:

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "<child id in the view>", insertable = false, updatable = false)
private Child child;


这篇关于懒惰的一对一春天JPA和建立“动态”的JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆