我将课程User
定义为
@Entity
@Table(name = "users")
@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class, property = "jsonUUID")
public class User implements Serializable, UserDetails
{
private static final long serialVersionUID = -7035881497059422985L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
protected String firstname;
protected String lastname;
protected String username;
protected ProfessionalCategory professional;
protected String companyName;
@Email
protected String email;
protected String password;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable
(
name = "role_user",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
protected Set<Role> roles;
}
当我在/users/{id}
上执行GET请求时,我希望Hibernate从用户的所有字段中获取值并返回“完整”对象。但是当我在/users/
上执行GET请求时,我想返回一个仅包含firstname
和lastname
的用户列表。我不仅希望杰克逊在序列化期间忽略某些字段,我还希望Hibernate不要获取它不需要的数据(因为我使用连接时为每个用户获取所有角色的成本非常高表)。
我知道我可以编写自己的SQL查询,但是我会放弃使用Hibernate的好处。那么有一种解决这个问题的优雅方式吗?
答案 0 :(得分:0)
最优雅的解决方案是使用Hibernate标准并在DAO中指定两种不同的方法。一种方法将根据其ID获取单个用户,另一种方法将使用ProjectionList
获取仅使用名字和姓氏填充的所有用户的列表。
public List<User> getAllUsers() {
Criteria query = sessionFactory.getCurrentSession().createCriteria(User.class);
query.setProjection(Projections.projectionList()
.add(Projections.property("firstName"), "firstName")
.add(Projections.property("lastName"), "lastName"))
.setResultTransformer(Transformers.aliasToBean(User.class));
return query.list();
}
上述代码导致Hibernate仅从数据库中获取firstName
和lastName
字段,然后使用User
将结果映射回ResultTransformer
类。这种方法不太理想,因为没有填充所有字段令人困惑。
理想的解决方案是懒洋洋地加载你的角色集合,这样Hibernate只会根据请求加载它。有关如何进行设置的详细信息,请参阅我的问与答here。