Home JPA: Fixed value join columns in collection of elements
Reply: 0

JPA: Fixed value join columns in collection of elements

ST-DDT
1#
ST-DDT Published in 2017-12-06 10:14:39Z

I would like to reduce the total number of similar tables in my database by using a fixed identifier in each join.

Currently my entity class looks like this:

public class Group {

    [...]

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(
            name = "group_admins",
            joinColumns = @JoinColumn(name = "group_id"))
    @Column(name = "name", unique = true, nullable = false)
    @OrderBy
    private Set<String> admins = new LinkedHashSet<>();

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(
            name = "group_moderators",
            joinColumns = @JoinColumn(name = "group_id"))
    @Column(name = "name", unique = true, nullable = false)
    @OrderBy
    private Set<String> moderators = new LinkedHashSet<>();     

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(
            name = "group_user",
            joinColumns = @JoinColumn(name = "group_id"))
    @Column(name = "name", unique = true, nullable = false)
    @OrderBy
    private Set<String> users = new LinkedHashSet<>();

    [...]

}

And this causes it to create 1+3=4 tables. 3 of them share the exact same columns. Now I would like to reduce this to 1+1=2 tables like that: https://docs.oracle.com/html/E13946_05/ref_guide_mapping_notes_nonstdjoins.html

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(
            name = "person",
            joinColumns = {
                    @JoinColumn(name = "group_id", referencedColumnName="id"),
                    @JoinColumn(name = "person.type", referencedColumnName="'user'")
            })
    @Column(name = "name", unique = true, nullable = false)
    @OrderBy
    private Set<String> users = new LinkedHashSet<>();

Which I expect to create a table like this:

  • Person
    • group_id: int
    • type: varchar [either of: 'user', 'moderator', 'admin']
    • name: varchar

But I always end up with an exception similar to this one:

Caused by: org.hibernate.MappingException: Unable to find column with logical name: 'user' in group
    at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:858) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:243) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1611) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1352) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:810) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:735) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1621) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1589) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:858) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:885) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]

It does not even try to execute the SQL.

I also tried @DescriminatorColumn, but that does not even apply to attributes.

Is there a way to do that without using an extra entity/embeddable for that?

I use

  • Java 8
  • Hibernate 5.2.12
  • Spring Boot
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.277784 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO