Как использовать @NamedEntityGraph и @JsonIdentityInfo для циклической ссылки (весенняя загрузка) - PullRequest
0 голосов
/ 17 февраля 2020

Я начинаю использовать Hibernate и хочу знать, как правильно использовать @NamedEntityGraph. У меня есть «Базовый» класс, в котором есть поля аудита с пользователем, который создал, изменил и удалил регистр, у всех моих таблиц будут эти поля, но у таблицы «Пользователь» тоже есть поля аудита, поэтому у меня возникают некоторые проблемы .

У меня есть этот код:

@MappedSuperclass
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public abstract class Base{
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Access(AccessType.PROPERTY) @Column(name = "id")
    protected Long id;
    @Column(name = "name", length = 150) @NotNull
    protected String name;
    @Embedded
    protected AuditFields audit;

    //...getters and setters
}

@Embeddable
public class AuditFields {

    @Column(name = "created_Date", nullable=false) @DateTimeFormat(pattern = "YYYY-MM-DDTHH:mm:ss:SSZ") @NotNull
    private ZonedDateTime createdDate;
    @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "created_User_Id")
    private User createdUser;
    @Column(name = "modified_Date", nullable=false) @DateTimeFormat(pattern = "YYYY-MM-DDTHH:mm:ss:SSZ") @NotNull
    private ZonedDateTime modifiedDate;
    @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "modified_User_Id")
    private User modifiedUser;
    @Column(name = "deleted_Date") @DateTimeFormat(pattern = "YYYY-MM-DDTHH:mm:ss:SSZ")
    private ZonedDateTime deletedDate;
    @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "deleted_User_Id")
    private User deletedUser;

    //...getters and setters
}



@Entity
@Table(name = "Users", schema = "system")
@AttributeOverride(name = "id", column = @Column(name = "user_Id"))
@NamedEntityGraphs(value = {
        @NamedEntityGraph(name = "normal"
                ,attributeNodes = { @NamedAttributeNode(value="audit", subgraph = "audit") }
                ,subgraphs = { @NamedSubgraph(name = "audit", attributeNodes = {
                                @NamedAttributeNode("createdUser"), @NamedAttributeNode("modifiedUser"), @NamedAttributeNode("deletedUser")
                                })
                }
        )
    })
public class User extends Base implements Serializable{
    private static final long serialVersionUID = 10000L;

    @Column(name = "password", length = 150)
    private String password;
    @Enumerated @Column(columnDefinition = "smallint") 
    private UserType userType;

    //...getters and setters
}



public interface IUsuarioDAO extends PagingAndSortingRepository<Usuario, Long> {
    @EntityGraph(value = "normal", type = EntityGraphType.FETCH)
    public Optional<Usuario> findById(long id);
}



@Configuration
public class MvcConfig implements WebMvcConfigurer{

    @Bean
    public Module datatypeHibernateModule() { 
        Hibernate5Module module= new Hibernate5Module();
        module.configure(Hibernate5Module.Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true); 
        return module;
    }
}

И когда я использую метод "findById" UsuarioDAO, начиная с контроллера, я получаю это json:

{
    "@id": 1,
    "id": 2,
    "audit": {
        "createdDate": "2020-02-15T19:00:00-05:00",
        "createdUser": {
            "@id": 2,
            "id": 1,
            "audit": {
                "createdDate": "2020-02-15T19:00:00-05:00",
                "createdUser": 2,
                "modifiedDate": "2020-02-15T19:00:00-05:00",
                "modifiedUser": 2,
                "deletedDate": null,
                "deletedUser": null
            },
            "name": "Batman",
            "tipoUsuario": "ADMIN"
        },
        "modifiedDate": "2020-02-15T19:00:00-05:00",
        "modifiedUser": 2,
        "deletedDate": null,
        "deletedUser": null
    },
    "name": "Superman",
    "userType": "ADMIN"
}

Если я не использую "@JsonIdentityInfo" в классе "Base", json повторяет пользовательский объект как бесконечный l oop

Но я только хочу получить это json:

{
    "id": 2,
    "audit": {
        "createdDate": "2020-02-15T19:00:00-05:00",
        "createdUser": {
            "id": 1,
            "name": "Batman"
        },
        "modifiedDate": "2020-02-15T19:00:00-05:00",
        "modifiedUser": {
            "id": 1,
            "name": "Batman"
        },
        "deletedDate": null,
        "deletedUser": null
    },
    "name": "Superman",
    "userType": "ADMIN"
}

Как я могу это сделать?

...