我想从数据库加载一个UserReference对象,但是从verifier属性我想只加载id,firstName和lastName,这样userReference看起来像这样:
{
"id": 1,
"company": "company1",
"companyContactName": "some name",
"companyPosition": "programmer",
"referenceDate": "02/04/2005",
"verifier": {
"id":1
"firstName": "Jane",
"lastName": "Smith"
"email":null,
"username":null,
"office:null,
"department":null
}
}
我使用了UserReference类的实体图,但是我使用的实体图加载了用户拥有的所有信息,包括电子邮件,用户名,办公室和部门。 有没有办法在子图中指定类似EntityGraphType.FETCH的东西,以便它只加载验证者的id,firstName和lastName?
这是我的UserReferenceRepository:
public interface UserReferenceRepository extends JpaRepository<UserReference, Long>{
@EntityGraph(value = "userReferenceGraph" , type = EntityGraphType.FETCH )
UserReference findOne(Long id);
}
UserReference类:
@Getter
@Setter
@EqualsAndHashCode (exclude = {"id", "verifier"})
@ToString(exclude = {"id"})
@Entity
@NamedEntityGraphs({
@NamedEntityGraph(
name = "userReferenceGraph",
attributeNodes = {
@NamedAttributeNode(value = "verifier", subgraph = "verifierGraph")
},
subgraphs = {
@NamedSubgraph(
name = "verifierGraph",
type = User.class,
attributeNodes = {
@NamedAttributeNode(value = "id"),
@NamedAttributeNode(value = "firstName"),
@NamedAttributeNode(value = "lastName")})})
})
public class UserReference {
@Id
@GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", referencedColumnName = "user_id", foreignKey = @ForeignKey (name = "FK_UserReference_UserHRDetails_user_id"))
@JsonIgnore
private UserHRDetails hrDetails;
private String company;
private String companyContactName;
private String companyPosition;
private Date referenceDate;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "verifier_id")
private User verifier;
}
和用户:
@Getter @Setter
@EqualsAndHashCode(exclude = {"id", "department", "company", "authorities", "hrDetails"})
@ToString(exclude = {"password"})
@Entity
@AllArgsConstructor
@Builder
public class User implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Access(value = AccessType.PROPERTY)
private Long id;
@Size(max = 50)
@Column(name = "first_name", length = 50)
private String firstName;
@Size(max = 50)
@Column(name = "last_name", length = 50)
private String lastName;
@Column(length = 100, unique = true, nullable = false)
private String email;
@Column(length = 50, unique = true, nullable = false)
private String username;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private Department department;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "office_id")
private Office office;
}
答案 0 :(得分:0)
我想你使用Jackson生成JSON。在这种情况下,这是杰克逊与实体图的战斗,前者没有机会赢得这场战斗。实体图只是构建SQL查询的提示,您只能告诉Hibernate不加载某些属性。 Hibernate在加载基本实体字段时仍然不支持实体图,请参阅https://hibernate.atlassian.net/browse/HHH-9270。但主要的问题是,杰克逊会在JSON生成过程中调用你的实体中的每个getter,而Hibernate将懒得加载它们而不考虑你的实体图。我只能提出@JsonIgnore用法,但这可能不像你需要的那样灵活。
答案 1 :(得分:0)
我遇到了相同的问题,并且看到了两种解决方法:
快速: 您可以在您的实体中执行一些@PostLoad动作,并使不需要的字段无效。
@PostLoad
private void postLoad() {
if (verifier != null) {
verifier.email = null;
verifier.office = null;
verifier.department = null;
}
}
正确: 另一种方法是通过将实体转换为DTO来保护您的实体。创建单独的POJO,并将您的User和UserReference转换为该DTO POJO类。在那里,您肯定会更好地控制自己的反应。