Java 使用Hibernate-仅获取指定字段(按名称)

Java 使用Hibernate-仅获取指定字段(按名称),java,hibernate,collections,hql,projection,Java,Hibernate,Collections,Hql,Projection,假设我们有两个这样的类: 人: @Entity @Table (name= "person") public class Person { @Id @GeneratedValue @Column(name = "Id") private Long id; @Column(name = "name") private String name; @Column(name = "phone") private String phone; @OneToMany(mappedBy = "bank")

假设我们有两个这样的类:

人:

@Entity
@Table (name= "person")
public class Person
{
@Id
@GeneratedValue
@Column(name = "Id")
private Long id;

@Column(name = "name")
private String name;

@Column(name = "phone")
private String phone;

@OneToMany(mappedBy = "bank")
private List<Bank> banks = new ArrayList<>();
}
我们只想获取某些字段:person.name、person.phone、person.bank.phone

我尝试过这样做:

List result = session.createCriteria( Person.class )
.setProjection( Projections.projectionList()
.add( Projections.property( "name" ) )
.add( Projections.property( "phone" ) )
.add( Projections.property( "banks.phone" ) )
).list();
但最终我得到了一个例外:

org.hibernate.QueryException: could not resolve property: banks.phone of: training.net5.Person
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:98)
at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:61)
at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1964)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:511)
at org.hibernate.criterion.PropertyProjection.toSqlString(PropertyProjection.java:67)
at org.hibernate.criterion.ProjectionList.toSqlString(ProjectionList.java:116)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getSelect(CriteriaQueryTranslator.java:379)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:110)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:92)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:97)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1651)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
at training.net5.MainClass.main(MainClass.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
could not resolve property: banks.phone of: training.net5.Person
org.hibernate.QueryException:无法解析属性:banks.phone of:training.net5.Person
位于org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
位于org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:98)
在org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:61)上
位于org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1964)
位于org.hibernate.loader.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:511)
位于org.hibernate.criteria.PropertyProjection.toSqlString(PropertyProjection.java:67)
位于org.hibernate.criteria.ProjectionList.toSqlString(ProjectionList.java:116)
位于org.hibernate.loader.CriteriaQueryTranslator.getSelect(CriteriaQueryTranslator.java:379)
位于org.hibernate.loader.criteria.CriteriaJoinWalker(CriteriaJoinWalker.java:110)
位于org.hibernate.loader.criteria.CriteriaJoinWalker(CriteriaJoinWalker.java:92)
位于org.hibernate.loader.criteria.CriteriaLoader.(CriteriaLoader.java:97)
位于org.hibernate.internal.SessionImpl.list(SessionImpl.java:1651)
位于org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
在training.net5.MainClass.main(MainClass.java:82)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:601)
位于com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
无法解析属性:banks.phone of:training.net5.Person
基本上,我们需要的是一种通过相对于根实体的路径只获取某些字段的方法。 所以我想知道我是否可以使用投影,或者我应该寻找另一种方法


p、 对不起,我的英语不是以英语为母语的。

你想要的是什么。如果您有一个包含许多列的表,可能需要对其进行规范化,而不是使用此技术。在您的代码中,
banks
具有
OneToMany
关系。你期待什么?

你能试着从另一个实体开始吗

List result = session.createCriteria( Bank.class )
.setProjection( Projections.projectionList()
.add( Projections.property( "person.name" ) )
.add( Projections.property( "person.phone" ) )
.add( Projections.property( "phone" ) )
).list();
也许应该是这样

@OneToMany(mappedBy = "person")
private List<Bank> banks = new ArrayList<>();
@OneToMany(mappedBy=“person”)
私有列表银行=新的ArrayList();

尝试在DAO中使用简单查询而不是条件来获取记录,顺便说一句,使用DAO,我们可以使用实体名称作为类名,字段名称作为数据成员,因此易于阅读。我希望获得一组银行电话号码作为第三个对象。我有一个REST服务,客户可以给我一个他需要的字段列表。作为回应,我必须向他发送一个JSON。也许你应该在银行设置
@OneToOne(fetch=FetchType.EAGER)
@OneToMany(mappedBy = "person")
private List<Bank> banks = new ArrayList<>();