【发布时间】:2017-12-20 09:16:54
【问题描述】:
我有一个具有多个属性的@Entity 类 Company,它引用了我的数据库中的一个公司表。其中一个代表 Map companyProperties,其中公司表由 company_properties 表扩展,属性以键值格式保存。
@Entity
@Table(name = "companies")
public class Company extends AbstractEntity {
private static final String TABLE_NAME = "companies";
@Id
@GeneratedValue(generator = TABLE_NAME + SEQUENCE_SUFFIX)
@SequenceGenerator(name = TABLE_NAME + SEQUENCE_SUFFIX, sequenceName = TABLE_NAME + SEQUENCE_SUFFIX, allocationSize = SEQUENCE_ALLOCATION_SIZE)
private Long id;
//some attributes
@ElementCollection
@CollectionTable(name = "company_properties", joinColumns = @JoinColumn(name = "companyid"))
@MapKeyColumn(name = "propname")
@Column(name = "propvalue")
private Map<String, String> companyProperties;
//getters and setters
}
实体管理器能够正确执行查找子句
Company company = entityManager.find(Company.class, companyId);
但是,我无法在此实体中执行 JPQL 查询并相应地检索地图。由于对象很大,我只需要在我的实体类中选择一些属性。我也不想按 companyProperties 过滤,而是要检索所有带有正确分配的 companyid 外键的它们。我试图做的是:
TypedQuery<Company> query = entityManager.createQuery("SELECT c.id, c.name, c.companyProperties " +
"FROM Company as c where c.id = :id", Company.class);
query.setParameter("id", companyId);
Company result = query.getSingleResult();
我得到的错误是:
java.lang.IllegalArgumentException:在 EntityManager 中创建查询时发生异常: 异常描述:编译问题 [SELECT c.id, c.name, c.companyProperties FROM Company as c where c.id = :id]。 [21, 40] 状态字段路径“c.companyProperties”无法解析为集合类型。 org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1616) org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1636) com.sun.enterprise.container.common.impl.EntityManagerWrapper.createQuery(EntityManagerWrapper.java:476)
尝试使用连接来完成(我得到的最远的一点是使用
Query query = entityManager.createQuery("SELECT c.id, c.name, p " +
"FROM Company c LEFT JOIN c.companyProperties p where c.id = :id");
没有给我正确的结果(它只返回属性的值,而不是它们的键值列表)。
如何定义正确的查询来执行此操作?
【问题讨论】:
-
你不能在结果子句中包含多值项,因为任何 JPQL 文档都会告诉你