Метод findAll () не возвращает недавно вставленную запись, когда отношение OneToOne сопоставлено с MapsId - PullRequest
1 голос
/ 21 июня 2019

У меня есть 2 класса сущностей с именами Post и PostDetails. Оба сопоставляются с отношением OneToOne, используя MapsId и совместно используют первичный ключ, как показано ниже.

Post.java

@Entity
@Table(name = "post")
@Data
public class Post implements Serializable
{
    private static final long serialVersionUID = -6698422774799518217L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NaturalId
    @Column(name = "title")
    private String title;

    @OneToOne(mappedBy = "post", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
    private PostDetail detail;

}

PostDetail.java

@Entity
@Table(name = "post_detail")
@Data
public class PostDetail implements Serializable
{
    private static final long serialVersionUID = -6699482774799518217L;

    @Id
    private Long id;

    @Column(name = "created_on")
    private Date createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    @JoinColumn(name = "id")
    @JsonIgnore
    private Post post;

}

PostController.java

@RestController
@RequestMapping("/api/v1/post")
public class PostController
{
    private final PostRepository postRepository;

    private final PostDetailRepository postDetailRepository;

    public PostController(PostRepository postRepository, PostDetailRepository postDetailRepository)
    {
        this.postRepository = postRepository;
        this.postDetailRepository = postDetailRepository;
    }

    @GetMapping(path = "/create")
    public List<Post> createAndGetPosts()
    {

        Post post=new Post();
        post.setId(new Random().nextLong());
        post.setTitle("First Post");
        post=postRepository.saveAndFlush(post);

        PostDetail postDetail =new PostDetail();
        postDetail.setCreatedBy("Admin");
        postDetail.setCreatedOn(Date.from(Instant.now()));
        postDetail.setPost(post);
        postDetailRepository.saveAndFlush(postDetail);

        return postRepository.findAll(Sort.by(Sort.Direction.DESC,"id"));
    }


}

В классе Post Controller я создаю объект Post (сохраняю его в БД), затем передаю его в объект PostDetail, затем сохраняю в базу данных, используя Spring Data JPA. Все работает как положено. Но когда я сразу получаю список записей, через метод postRepository.findAll(Sort.by(Sort.Direction.DESC,"id")); я получаю значение null для объекта PostDetail внутри Post, как показано ниже.

Ответ:

[
  {
    "id": 2,
    "title": "First Post",
    "detail": null
  },
  {
    "id": 1,
    "title": "Post1",
    "detail": {
      "id": 1,
      "createdOn": "2019-06-21T03:31:43.000+0000",
      "createdBy": "Admin"
    }
  }
]

Но когда я снова отправляю запрос от внешнего интерфейса для списка, я получаю правильный ответ. Я попытался поместить оператор flush и второй оператор findAll () перед запросом, ничего не помогло.

1 Ответ

1 голос
/ 21 июня 2019

Это происходит потому, что вы получаете точно такой же экземпляр, который был возвращен из saveAndFlush и сохранен в переменной post.

Hibernate не обновляет Post.detail, когда вы делаете postDetail.setPost(post).

Чтобы исправить это, вы можете установить detail вручную или исключить Post экземпляр из кэша после сохранения, что вынудит hibernate перезагрузить его из БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...