【问题标题】:JPA: How to express a unique constraint including an @ElementCollection column?JPA:如何表达包含@ElementCollection 列的唯一约束?
【发布时间】:2013-01-18 08:21:50
【问题描述】:

这是我的 JPA 实体类:

@Cacheable
@Entity
public class JpaItemSearchRequest implements ItemSearchRequest {

    @Id
    @GeneratedValue
    private long id;

    @Enumerated(EnumType.STRING)
    private SearchIndex searchIndex;

    private String browseNode;
    private String keywords;

    @Enumerated(EnumType.STRING)
    @ElementCollection
    private Set<ResponseGroup> responseGroups = new HashSet<ResponseGroup>();

    private int itemPage;

    @Enumerated(EnumType.STRING)
    private Locale locale;

    ... end of fields ...
}

SearchIndexResponseGroupLocale 是枚举。

这个类有一个相当复杂的唯一约束: (searchIndex, browseNode, keywords, responseGroups, itemPage, locale) 被认为是唯一的。

所以我在类中添加了以下约束注解:

@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "searchIndex", "browseNode", "keywords", "responseGroups", "itemPage", "locale" }) })

当我尝试锻炼我的班级时,出现以下异常:

 org.hibernate.AnnotationException: Unable to create unique key constraint (searchIndex, browseNode, keywords, responseGroups, itemPage, locale) on table JpaItemSearchRequest: database column responseGroups not found. Make sure that you use the correct column name which depends on the naming strategy in use (it may not be the same as the property name in the entity, especially for relational types)
    at org.hibernate.cfg.Configuration.buildUniqueKeyFromColumnNames(Configuration.java:1584) ~[hibernate-core-4.1.7.Final.jar:4.1.7.Final]
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1386) ~[hibernate-core-4.1.7.Final.jar:4.1.7.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737) ~[hibernate-core-4.1.7.Final.jar:4.1.7.Final]
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94) ~[hibernate-entitymanager-4.1.7.Final.jar:4.1.7.Final]
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905) ~[hibernate-entitymanager-4.1.7.Final.jar:4.1.7.Final]
    ... 74 common frames omitted

(我使用Hibernate 4.1.7.Final作为JPA实现/服务提供者)

例外要点是:database column responseGroups not found.

如果我没有在后台为我的单个实体类指定该约束,Hibernate 会生成两个表:一个用于所有“简单”实体数据,另一个用于Set&lt;ResponseGroup&gt; responseGroups 实体数据:

CREATE TABLE `jpaitemsearchrequest` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `browseNode` VARCHAR(255) NULL DEFAULT NULL,
    `itemPage` INT(11) NOT NULL,
    `keywords` VARCHAR(255) NULL DEFAULT NULL,
    `locale` VARCHAR(255) NULL DEFAULT NULL,
    `searchIndex` VARCHAR(255) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=3;

...

CREATE TABLE `jpaitemsearchrequest_responsegroups` (
    `JpaItemSearchRequest_id` BIGINT(20) NOT NULL,
    `responseGroups` VARCHAR(255) NULL DEFAULT NULL,
    INDEX `FKC217757B99AE0422` (`JpaItemSearchRequest_id`),
    CONSTRAINT `FKC217757B99AE0422` FOREIGN KEY (`JpaItemSearchRequest_id`) REFERENCES `jpaitemsearchrequest` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

如何正确表达我的约束?


编辑

这个问题曾经读过:
JPA: Unique constraint across a Set (...unique constraint on another table)

进一步思考我的问题,我确信它可以归结为以下问题:
JPA:如何表达包含@ElementCollection 列的唯一约束?

【问题讨论】:

  • 这是不可能的。您不能对另一个表的一组列和一组连接行设置唯一约束。
  • ...什么是解决方法? ...我应该将@ElementCollection Set&lt;ResponseGroup&gt; responseGroups 转换为规范的String 表示吗?
  • 这将导致无法查询响应组。但如果这个独特的约束是如此重要,它可能是一种选择。
  • ...我可以利用实现的方法Set&lt;ResponseGroup&gt; ItemSearchRequest.getResponseGroups()void ItemSearchRequest.getResponseGroups(Set&lt;ResponseGroup&gt;)String 表示和Set&lt;ResponseGroup&gt; 表示之间进行转换...但我想这种转换并不重要自动开启任何与 JPA 相关的查询(...例如 select * from JpaItemSearchRequest where responseGroups="ENUM_A,ENUM_B,ENUM_C".

标签: java hibernate jpa


【解决方案1】:

集合表中列的唯一约束可以通过将@CollectionTable与元素集合一起使用来定义。

@CollectionTable(
    uniqueConstraints= @UniqueConstraint(columnNames={"col1","col2"})
)

如前所述,这些是映射元素集合的表格列。无法对多个表中的列进行唯一约束。

【讨论】:

    猜你喜欢
    • 2011-10-02
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2011-03-25
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多