Я начинаю использовать 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"
}
Как я могу это сделать?