Аудит: ревизия родительской сущности при модификации потомка (Javers / Envers / ... + Hibernate) - PullRequest
0 голосов
/ 30 марта 2019

У меня есть тип родительского объекта в моем приложении, который должен быть версионирован (проверен), что я имею в виду: каждый раз, когда изменение в нем сохраняется, или в любом из его n-глубоких дочерних объектов, новая ревизиядолжен быть создан.

@Entity class Document {
    @Id String name;
    // some props ...
    @OneToMany List<Page> pages;
    // getters and setters ...
}

@Entity class Page {
    @Id Long number;
    @ManyToOne Document document;
    // some props ...
    String header;
    // getters and setters ...
}

В приведенном выше примере, если я должен был изменить заголовок страницы, новая редакция должна сохраняться для всей сущности Document:

// retrieve document
Document document = documentRepository.findById(myBookId);
// change something on first found page
document.getPages().iterator().next().setHeader("Hello World");
// persist the document
documentRepository.save(document);
// new revision of the document!

Я думал об использовании Javers или Envers , но, похоже, никто из них не может это сделать.

Кто-нибудь из вас знает, как сделать что-то подобное на техЛИЭС?Или знаете какую-нибудь библиотеку, которую я могу использовать для этой цели?

1 Ответ

1 голос
/ 09 апреля 2019

Вы можете достичь этого в Javers, если вы отобразите Page class как ValueObject, а затем, если будете использовать Shadow query.Также вы должны фиксировать Document все время:

    @Entity
    class Document {
        @Id String name
        @OneToMany List<Page> pages

        @Override
        String toString() {
            "Document $name, pages:$pages"
        }
    }

    @org.javers.core.metamodel.annotation.ValueObject
    @Entity
    @ToString
    class Page {
        @Id Long number
        @ManyToOne Document document
        String header

        @Override
        String toString() {
            "Page $number, $header"
        }
    }

    def "should treat Document as aggregate"(){
      given:
      def javers = JaversBuilder.javers().build()

      def doc = new Document(name:"1", pages: [new Page(header:"a"), new Page(header:"b")])
      javers.commit("author", doc)

      when:
      doc = new Document(name:"1", pages: [new Page(header:"a"), new Page(header:"ccc")])
      javers.commit("author", doc)

      def shadows = javers.findShadows(QueryBuilder.byClass(Document).build())

      then:
      shadows

      shadows.forEach{s -> println(s.commitMetadata.commitDate.toString() + " " + s.get())}
    }

вывод:

23:25:47.297 [main] INFO  org.javers.core.Javers - Commit(id:1.0, snapshots:3, author:author, changes - NewObject:3), done in 56 millis (diff:45, persist:11)
23:25:47.315 [main] INFO  org.javers.core.Javers - Commit(id:2.0, snapshots:1, author:author, changes - ValueChange:1), done in 17 millis (diff:17, persist:0)
23:25:47.337 [main] DEBUG org.javers.JQL - SHALLOW query: 4 snapshots loaded (entities: 1, valueObjects: 3)
23:25:47.358 [main] DEBUG org.javers.JQL - queryForShadows executed: 
2019-04-08T23:25:47.298618 Document 1, pages:[Page null, a, Page null, ccc]
2019-04-08T23:25:47.275570 Document 1, pages:[Page null, a, Page null, b]
...