【发布时间】:2019-01-23 18:35:14
【问题描述】:
假设我有 2 个实体:Application 和 Organization。它们是多对多相关的
组织:
@Entity
@Table(name = "organizations")
public class Organization
{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "organizationIdGenerator")
private long id; // primary key
@AttributeOverride(name = "id", column = @Column(name = "organization_id", unique = true, updatable = false))
@Embedded
private OrganizationId organizationId;
@AttributeOverride(name = "id", column = @Column(name = "application_id"))
@CollectionTable(name = "organization_applications")
@ElementCollection
private Set<ApplicationId> applications = new HashSet<>(); // there is no explicit @Many-to-many connection between applications and organizations
private String name;
// other data
}
应用:
@Entity
@Table(name = "applications")
public class Application
{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "applicationIdGenerator")
private long id; // primary key
@AttributeOverride(name = "id", column = @Column(name = "application_id", unique = true, updatable = false))
@Embedded
private ApplicationId applicationId;
private String label;
// other data
}
由于它们是多对多相关的,因此在关系数据库中我有以下表格:
organizationsapplicationsorganization_applications
表 organization_applications 是使用以下 liquibase-migration 创建的:
<createTable tableName="organization_applications">
<column name="organization_id" type="bigint">
<constraints nullable="false" foreignKeyName="organization_application_organization_id_fk"
referencedTableName="organizations" referencedColumnNames="id"/>
</column>
<column name="application_id" type="varchar(50)">
<constraints nullable="false"/>
</column>
</createTable>
我想做的是在一个查询中为特定组织获取应用程序 (List<Application>)
我可以通过获取特定组织的 applicationIds 来做到这一点(比如说,organizationId = 1)并将它们与applications 一起使用如下查询:
select apps.application_id, apps.label
from organization_applications org_apps
join applications apps
on (apps.application_id = org_apps.application_id and org_apps.organization_id = 1)
但是当我尝试使用这样的 JPQL 查询来完成此操作时:
SELECT new List(o.applications) FROM Organization o WHERE o.organizationId.id = 1
我收到以下查询,然后出现异常:
Hibernate:
/* SELECT
new List(o.applications)
FROM
Organization o
WHERE
o.organizationId.id = :org_id */ select
. as col_0_0_ // <-- problem here. why is there just a dot?
from
organizations organizati0_
inner join
organization_applications applicatio1_
on organizati0_.id=applicatio1_.organization_id
where
organizati0_.organization_id=?
SqlExceptionHelper : SQL Error: 20000, SQLState: 42X01
SqlExceptionHelper : Syntax error: Encountered "." at line 1, column 102.
似乎在这样的关系中,实体通过自定义 id 字段(applicationId、organiationId)相关联,hibernate 无法创建查询。
知道我该怎么做吗?
提前致谢!
更新:
ApplicationId 包含一些验证,如下所示:
public class ApplicationId
{
private String id;
// constructor and getters
}
OrganizationId看起来一模一样
【问题讨论】:
-
您尚未在引用的 2 个实体之间定义实际的关系。您只需拥有一组未定义的嵌入对象。这不是 M-N 关系
-
而且新的列表在查询中是不可能的。你想达到什么目的?
-
@BillyFrost 我添加了一个迁移,它创建了一个定义它们的关系的表,并且由于
organization不是该关系的所有者,因此没有明确定义的关系(通过@ManyToMany)跨度> -
@SimonMartinelli,我正在尝试获取 属于特定组织的应用程序列表。由于 JPQL 需要一个将由结果值填充的 DTO,并且由于我试图获取应用程序列表,我应该使用什么类型?此外,如果我需要一个与
One-to-Many相关的属性(例如,组织的电话号码),select new List(...)也很适合。看看this answer -
试试 SELECT o.applications FROM Organization o WHERE o.organizationId.id = 1 看看你会在结果列表中找到什么类型。
标签: java hibernate jpa hql jpql