简体   繁体   English

JpaRepository findAll() 正在获取嵌套对象

[英]JpaRepository findAll() is fetching nested objects

I searched about this problem the whole morning and I couldn't get a valid solution.我整个上午都在搜索这个问题,但找不到有效的解决方案。

I have the following code:我有以下代码:

@Entity
@Getter
@Setter
@ToString
@EqualsAndHashCode
@Table(name = Tag.TABLE_NAME)
@NoArgsConstructor
public class Tag {
  static final String TABLE_NAME = "blog_tags";
  private static final String ID_TAG = "idTag";
  private static final String FIELD_TAG = "tag";
  private static final String FK_POST = "FK_Post";

  @Id
  @NotNull
  @Column(name = ID_TAG, unique = true)
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @NotNull
  @Column(name = FIELD_TAG, unique = true)
  private String tagName;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = FK_POST, insertable = false, updatable = false)
  private Post post;

  @NotNull
  @Column(name = FK_POST)
  private Long fkPost;

}

The entity Post also has a JPA @OneToMany annotation with a mappedBy and fetch LAZY.实体 Post 也有一个 JPA @OneToMany 注释,带有一个 mappingBy 和 fetch LAZY。

However, when I use the default method findAll/findOne to retrieve my tags it also makes a select to retrieve posts.但是,当我使用默认方法 findAll/findOne 检索我的标签时,它也会选择检索帖子。

What can I do to only retrieve the three fields of the Tag Entity without making a custom query?如何只检索标签实体的三个字段而不进行自定义查询? I want to use the methods provided by JpaRepository.我想使用 JpaRepository 提供的方法。

Thanks in advance.提前致谢。

Edit: Post Entity编辑:发布实体

@Entity
@NoArgsConstructor
@Table(name = Post.TABLE_NAME)
public class Post {
  static final String POST_AUTHOR_ENTITYGRAPH = "Post.author";
  private static final String MAPPED_BY_POST = "post";
  static final String TABLE_NAME = "blog_posts";
  private static final String FIELD_POST_VISITS = "post_visits";
  private static final String FIELD_POST_MODIFIED = "post_modified";
  private static final String FIELD_POST_ENABLED = "post_enabled";
  private static final String FIELD_POST_DATE = "post_date";
  private static final String FIELD_POST_CONTENT = "post_content";
  private static final String FIELD_COMMENTS_ENABLED = "comments_enabled";
  private static final String FIELD_TITLE = "post_title";
  private static final String ID_POST = "idPost";
  private static final String FK_AUTHOR = "FK_Author";

  @NotNull
  @Column(name = FIELD_COMMENTS_ENABLED)
  private boolean commentsEnabled;

  @NotNull
  @Column(name = FIELD_POST_CONTENT, columnDefinition = "LONGTEXT")
  private String postContent;

  @NotNull
  @Column(name = FIELD_POST_DATE, unique = true, columnDefinition = "DATETIME")
  private LocalDateTime postDate;

  @NotNull
  @Column(name = FIELD_POST_ENABLED)
  private boolean postEnabled;

  @Id
  @Column(name = ID_POST, unique = true)
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @NotNull
  @Column(name = FIELD_POST_MODIFIED, columnDefinition = "DATETIME")
  private LocalDateTime postModified;

  @NotNull
  @Column(name = FIELD_TITLE, unique = true)
  private String postTitle;

  @NotNull
  @Column(name = FIELD_POST_VISITS)
  private Long postVisits;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = FK_AUTHOR, insertable = false, updatable = false)
  private User author;

  @NotNull
  @Column(name = FK_AUTHOR)
  private Long fkAuthor;

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "blog_posts_categories", joinColumns = @JoinColumn(name = ID_POST, referencedColumnName = ID_POST), //
      inverseJoinColumns = @JoinColumn(name = Category.ID_CATEGORY, referencedColumnName = Category.ID_CATEGORY))
  private Set<Category> categories;

  @OneToMany(mappedBy = MAPPED_BY_POST, fetch = FetchType.LAZY)
  private Set<Image> images;

  @OneToMany(mappedBy = MAPPED_BY_POST, fetch = FetchType.LAZY)
  private Set<Tag> tags;

 // Autogenerated getters & setters

  @Override
  public String toString() {
    return "Post [commentsEnabled=" + commentsEnabled + ", postContent=" + postContent
        + ", postDate=" + postDate + ", postEnabled=" + postEnabled + ", id=" + id
        + ", postModified=" + postModified + ", postTitle=" + postTitle + ", postVisits="
        + postVisits + "]";
  }

Edit: Added TagController编辑:添加了标签控制器

@Api(tags = "Tags")
@RestController
@RequestMapping(TagController.REST_API)
public class TagController {

  static final String REST_API = "/tags";
  public static final String ID_TAG = "ID_TAG";
  public static final String PARAM_URL = "/{" + ID_TAG + "}";

  private final JpaRepository<Tag,Long> repository;
  private final TagMapper mapper;

  @Autowired
  TagController(final JpaRepository<Tag,Long> repository,
      final TagMapper mapper) {
    this.repository = repository;
    this.mapper = mapper;
  }

  @ApiOperation(value = "Find all the tags from database.", tags = "tags")
  @GetMapping(produces = "application/json")
  public List<TagDto> getAllTags() {
    return mapper.entityToDtoList(repository.findAll());
  }

}

SQL OUTPUT SQL 输出

Hibernate: select tag0_.idTag as idTag1_6_, tag0_.FK_Post as FK_Post2_6_, tag0_.tag as tag3_6_ from blog_tags tag0_
Hibernate: select post0_.idPost as idPost1_3_0_, post0_.FK_Author as FK_Autho3_3_0_, post0_.comments_enabled as comments2_3_0_, post0_.post_content as post_con4_3_0_, post0_.post_date as post_dat5_3_0_, post0_.post_enabled as post_ena6_3_0_, post0_.post_modified as post_mod7_3_0_, post0_.post_title as post_tit8_3_0_, post0_.post_visits as post_vis9_3_0_ from blog_posts post0_ where post0_.idPost=?
Hibernate: select user0_.idUser as idUser1_7_0_, user0_.user_email as user_ema2_7_0_, user0_.passwordHash as password3_7_0_, user0_.FK_Role as FK_Role8_7_0_, user0_.passwordSalt as password4_7_0_, user0_.user_enabled as user_ena5_7_0_, user0_.user_name as user_nam6_7_0_, user0_.user_website as user_web7_7_0_ from blog_user user0_ where user0_.idUser=?
Hibernate: select userrole0_.idUserRole as idUserRo1_8_0_, userrole0_.user_role as user_rol2_8_0_ from blog_user_roles userrole0_ where userrole0_.idUserRole=?

Edit:编辑:

After looking over the code once more, it's possible that another part of the application is attempting to get your Post 's.再次查看代码后,应用程序的另一部分可能正在尝试获取您的Post Calling the getter for Post will tell Hibernate to fetch the entity.Post调用 getter 将告诉 Hibernate 获取实体。

This can sometimes happen even if you're not explicitly invoking the getter.即使您没有明确调用 getter,有时也会发生这种情况。 Jackson may be calling it when attempting to write your response or it could even be invoked through a call to toString . Jackson 在尝试编写您的响应时可能会调用它,或者甚至可以通过调用toString来调用它。 For example, if you're looking at this response at a breakpoint in your IDE it's possible that your IDE's debugger is invoking toString behind the scenes in order to populate the debugger UI with your object's info.例如,如果您在 IDE 的断点处查看此响应,则 IDE 的调试器可能会在幕后调用 toString,以便使用您的对象信息填充调试器 UI。

It's likely Jackson is invoking your Post getter when serializing your List<Tag> response to JSON.在将您的List<Tag>响应序列化为 JSON 时,Jackson 很可能正在调用您的Post getter。 Your may want to try adding the correct Jackson JSON parser to support Hibernate datatypes.您可能想尝试添加正确的 Jackson JSON 解析器以支持 Hibernate 数据类型。

https://github.com/FasterXML/jackson-datatype-hibernate https://github.com/FasterXML/jackson-datatype-hibernate

For example, try adding the datatype to your pom例如,尝试将数据类型添加到您的 pom

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>

And adding a bean for the correct module.并为正确的模块添加一个 bean。

@Bean
public Module hibernateModule() {
    return new Hibernate5Module();
}

You should take a look and make sure you're using the correct module for your version of Hibernate.您应该查看一下并确保您使用的是适合您的 Hibernate 版本的正确模块。

thank you very much for your answers.非常感谢您的回答。 Finally I could resolve the problem.最后我可以解决这个问题。

It actually resided in the pom configuration, I forgot to delete a plugin related to Hibernate that, I don't know why, forced hibernate to fetch the nested objects.它实际上驻留在 pom 配置中,我忘记删除与 Hibernate 相关的插件,我不知道为什么,强制 Hibernate 获取嵌套对象。

Thank you everyone for helping me.谢谢大家帮助我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM