This is my JPA entity class:
@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 ...
}
SearchIndex
, ResponseGroup
, and Locale
are enums.
This class has a rather complex unique constraint: a combination of
(searchIndex, browseNode, keywords, responseGroups, itemPage, locale)
is considered unique.
So I added the following constraint annotation to the class:
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "searchIndex", "browseNode", "keywords", "responseGroups", "itemPage", "locale" }) })
When I try to exercise my class, I get the following exception:
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
(I use Hibernate 4.1.7.Final as the JPA implementation/service provider)
The exception gist is: database column responseGroups not found.
If I don't specify that constraint, behind the scenes, for my single entity class, Hibernate generates two tables: One for all the "simple" entity data, and one additional table for the Set<ResponseGroup> responseGroups
entity data:
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;
How can I correctly express my constraint?
This question used to read:
JPA: Unique constraint across a Set (...unique constraint on another table)
Further thinking about my problem, I'm convinced it can be boiled down to the following question:
JPA: How to express a unique constraint including an @ElementCollection column?
Unique constraint over columns in collection table can be defined by using @CollectionTable with element collection.
@CollectionTable(
uniqueConstraints= @UniqueConstraint(columnNames={"col1","col2"})
)
As said, those are columns of table where element collection is mapped. There is no way to have unique constraint over columns in multiple tables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With