Search code examples
javahibernatehql

how to access a java hibernate manytomany mapping table


I just tried to do my first steps with hibernate.

Therefore I generated a simple database with two tables (geraet and stadort).

The tables have a many to many mapping and hibernate creates a third mapping-table (as expected).

(The picture just shows the primary keys)

enter image description here

After inserting some values I would like to query the database. I would like to get all entries from one table (geraet) which have more than one occurrence in the mapping table.

In regular SQL I would do something like:

select ge.* 
from geraet ge
inner join gsm g on ge.id=g.geraet_id
inner join standort s on g.standorts_id=s.id 
group by ge.id 
having count (g.geraet_id)>1

Unfortunately I can’t figure out, how to do this in hibernate.

My last try was writing a java class for the mapping table. Unfortunately I wasn’t able to access this table using hibernate because the auto generated mapping table has not a single primary key column (the primary key is the combination over both columns).

Now I'm thinking about splitting my many to many mapping in two independent one to many mappings. But I hope that there is a more efficient way?

The important Java code for my last try looks like:

package myclasses;

import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table (name="gsm")
public class GSM {

    private int geraet_id;
    private int standorts_id;
    public int getGeraet_id() {
        return geraet_id;
    }
    public void setGeraet_id(int geraet_id) {
        this.geraet_id = geraet_id;
    }
    public int getStandorts_id() {
        return standorts_id;
    }
    public void setStandorts_id(int standorts_id) {
        this.standorts_id = standorts_id;
    }
}

public class Main {

    public static void main(String[] args) {
        ...
        List<GSM>gsmlist = session.createCriteria(GSM.class).list();
        for (GSM aktuell : gsmlist)
        {
            System.out.println(aktuell.getGeraet_id()+" "+aktuell.getStandorts_id());
        }
        session.getTransaction().commit();
        session.close();
        factory.close();
    }
}

That results in the following exception:

Exception in thread "main" org.hibernate.AnnotationException: No identifier specified for entity: myclasses.GSM
at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:266)
at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:211)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:731)
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:249)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:222)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:691)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
at myclasses.Main.main(Main.java:24)

Solution

  • All you need is a standard many-to-many mapping, and the query

    select g from Geraet g where SIZE(g.stadorts) > 1