Hibernate возвращает значение NULL для свойства объекта, аннотированного @Formula после сохранения объекта - PullRequest
0 голосов
/ 24 июня 2018

У меня есть простой класс, как вы можете видеть ниже:

@Entity
@Table(name = "post")
public class Post {

    @Id
    @GeneratedValue
    Long id;

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

    @Formula("(select current_date())")
    Date currentDate;

    @OneToMany(mappedBy = "post")
    Set<PostComment> commentList = new HashSet<>();
}

и я хочу обновить эту сущность в сервисе:

@Service
@Transactional
public class PostService {

    private final PostRepository postRepository;

    public PostService(PostRepository postRepository) {
        this.postRepository = postRepository;
    }

    @Transactional
    public Post save(Post entity) {
        Post post = postRepository.saveAndFlush(entity);
        System.out.println("current_date: " + post.getCurrentDate());
        post.getCommentList().forEach(pc -> System.out.println(pc.getReview()));
        return post;
    }
}

И когда я проверяю журналы гибернации, он сначалаselect все поля Post сущности, но когда я вызываю post.getCurrentDate() (с пометкой @Formula), возвращается null:

Hibernate: select post0_.id as id1_0_0_, post0_.title as title2_0_0_, (select current_date()) as formula0_0_ from post post0_ where post0_.id=?
Hibernate: update post set title=? where id=?
current_date: null
Hibernate: select commentlis0_.post_id as post_id3_1_0_, commentlis0_.id as id1_1_0_, commentlis0_.id as id1_1_1_, commentlis0_.post_id as post_id3_1_1_, commentlis0_.review as review2_1_1_ from post_comments commentlis0_ where commentlis0_.post_id=?
review

Почему он возвращает и регистрирует commentList, но нене вернешься currentDate?это ошибка гибернации?

ПРИМЕЧАНИЕ

Я поместил полный пример проекта в github, который вы можете увидеть здесь .

1 Ответ

0 голосов
/ 24 июня 2018

Я написал тестовый пример моего высокопроизводительного хранилища GitHub-java-persistence , которое работает как шарм.

Сущность выглядит следующим образом:

@Entity(name = "Event")
@Table(name = "event")
public static class Event {

    @Id
    private Long id;

    @Formula("(SELECT current_date)")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdOn;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getCreatedOn() {
        return createdOn;
    }

    public void setCreatedOn(Date createdOn) {
        this.createdOn = createdOn;
    }
}

Обратите внимание, что свойство Date также использует аннотацию @Temporal.

Теперь, чтобы эмулировать ваш вариант использования, я написал следующую логику доступа к данным:

Event event = new Event();
event.setId(1L);

entityManager.persist(event);
entityManager.flush();

entityManager.refresh(event);

assertNotNull(event.getCreatedOn());

Обратите внимание наrefresh вызов, который необходим, поскольку объект кэшируется на persist, и мы хотим заново извлечь его из БД.

И при его выполнении Hibernate генерирует следующие операторы:

Query:["insert into event (id) values (?)"], Params:[(1)]
Query:["select formulacur0_.id as id1_0_0_, (SELECT current_date) as formula0_0_ from event formulacur0_ where formulacur0_.id=?"], Params:[(1)]

И тестовый пример работает просто отлично.Просто сравните отладочный пример с моим и посмотрите, почему ваш не работает, а мой работает.

...