hibernatejpaguiceguice-persist

Hibernate: Unable to locate persister: java.math.BigDecimal


I am trying to combine guice, jpa and hibernate. The initialization of hibernate looks good, until i try to access a mapped class trough a DAO. I found all the help requests, but my problem is (for now) not a "custom-class" (at least I dont think so).

All together nothing special. I got my persistence.xml which defines my classes and a basic (persist, findById, remove) DAO for one of that classes.

public abstract class AbstractDao<E, K> implements Dao<E, K> {

    @Inject
    private EntityManager  manager;
    private final Class<E> entityClass;

    @SuppressWarnings("unchecked")
    public AbstractDao() {
        final ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
    }

    @Override
    public void persist(final E entity) {
        this.manager.persist(entity);
    }

    @Override
    public void remove(final E entity) {
        this.manager.remove(entity);
    }

    @Override
    public E findById(final K id) {
        return this.manager.find(this.entityClass, id);
    }
}

If I try to access the database with that DAO like

final LayerDao dao = this.layerDaoProvider.get();
final Layer layer = dao.findById(386L); //Tried with BigDecimal, Long

I get the following error (I get the exact same error with java.lang.Long):

Caused by: org.hibernate.UnknownEntityTypeException: Unable to locate persister: java.math.BigDecimal
    at org.hibernate.metamodel.internal.MetamodelImpl.locateEntityPersister(MetamodelImpl.java:637) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.internal.SessionImpl.locateEntityPersister(SessionImpl.java:2909) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.internal.SessionImpl.access$1800(SessionImpl.java:203) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.<init>(SessionImpl.java:2660) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.<init>(SessionImpl.java:2646) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.internal.SessionImpl.byId(SessionImpl.java:1181) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.internal.SessionImpl.find(SessionImpl.java:3357) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
    at org.hibernate.internal.SessionImpl.find(SessionImpl.java:3332) ~[hibernate-core-5.2.2.Final.jar:5.2.2.Final]
[..]

I did not expect to have problems with some java-core classes.

This are all my configured gradle dependencies:

compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21'    
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.6.2'
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.6.2'
// https://mvnrepository.com/artifact/com.google.inject/guice
compile group: 'com.google.inject', name: 'guice', version: '4.1.0'
// https://mvnrepository.com/artifact/com.google.inject.extensions/guice-persist
compile group: 'com.google.inject.extensions', name: 'guice-persist', version: '4.1.0'
// https://mvnrepository.com/artifact/com.cathive.fx/fx-guice
compile group: 'com.cathive.fx', name: 'fx-guice', version: '8.0.0'
// https://mvnrepository.com/artifact/org.hibernate/hibernate-core
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2+'

What am I missing? Do you need any more information to help me?

Edit #1: The mapped class i try to access. It is automatically created with Eclipse (latest JEE Edition):

import java.io.Serializable;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;


/**
 * The persistent class for the T_M_LAYER_NEU database table.
 * 
 */
@Entity
@Table(name="T_M_LAYER_NEU")
@NamedQuery(name="Layer.findAll", query="SELECT l FROM Layer l")
public class Layer implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name="T_M_LAYER_NEU_ID_GENERATOR", sequenceName="FIG_SYS_SEQ")
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="T_M_LAYER_NEU_ID_GENERATOR")
    @Column(unique=true, nullable=false, precision=38)
    private long id;

    @Column(nullable=false, precision=1)
    private BigDecimal component;

    @Column(name="DISPLAY_ORDER", nullable=false, precision=3)
    private BigDecimal displayOrder;

    @Column(nullable=false, precision=1)
    private BigDecimal exklusiv;

    @Column(name="GEOMETRIETYP_ID_FK", precision=2)
    private BigDecimal geometrietypIdFk;

    @Temporal(TemporalType.DATE)
    @Column(name="GUELTIG_BIS", nullable=false)
    private Date gueltigBis;

    @Temporal(TemporalType.DATE)
    @Column(name="GUELTIG_VON", nullable=false)
    private Date gueltigVon;

    @Column(nullable=false, precision=1)
    private BigDecimal isactive;

    @Column(nullable=false, precision=1)
    private BigDecimal iskulisse;

    @Column(nullable=false, precision=1)
    private BigDecimal isoverview;

    @Column(name="LAYERTYP_ID_FK", nullable=false, precision=2)
    private BigDecimal layertypIdFk;

    @Column(nullable=false, length=80)
    private String name;

    @Column(name="R_O", nullable=false, precision=1)
    private BigDecimal rO;

    @Column(name="SOURCE_ID", precision=38)
    private BigDecimal sourceId;

    @Column(name="\"SYSTEM\"", nullable=false, precision=1)
    private BigDecimal system;

    @Column(name="USE_COMPLETECACHE", nullable=false, precision=1)
    private BigDecimal useCompletecache;

    @Column(name="XML_DEF", length=100)
    private String xmlDef;

    //bi-directional many-to-one association to Label
    @ManyToOne
    @JoinColumn(name="LABEL_ID_FK")
    private Label label;

    //bi-directional many-to-one association to Symbol
    @ManyToOne
    @JoinColumn(name="SYM_ID_FK")
    private Symbol symbol;

    //bi-directional many-to-one association to Tabellen
    @ManyToOne
    @JoinColumn(name="LAYERDEF_ID_FK")
    private Tabellen table;

    public Layer() {
    }

    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public BigDecimal getComponent() {
        return this.component;
    }

    public void setComponent(BigDecimal component) {
        this.component = component;
    }

    public BigDecimal getDisplayOrder() {
        return this.displayOrder;
    }

    public void setDisplayOrder(BigDecimal displayOrder) {
        this.displayOrder = displayOrder;
    }

    public BigDecimal getExklusiv() {
        return this.exklusiv;
    }

    public void setExklusiv(BigDecimal exklusiv) {
        this.exklusiv = exklusiv;
    }

    public BigDecimal getGeometrietypIdFk() {
        return this.geometrietypIdFk;
    }

    public void setGeometrietypIdFk(BigDecimal geometrietypIdFk) {
        this.geometrietypIdFk = geometrietypIdFk;
    }

    public Date getGueltigBis() {
        return this.gueltigBis;
    }

    public void setGueltigBis(Date gueltigBis) {
        this.gueltigBis = gueltigBis;
    }

    public Date getGueltigVon() {
        return this.gueltigVon;
    }

    public void setGueltigVon(Date gueltigVon) {
        this.gueltigVon = gueltigVon;
    }

    public BigDecimal getIsactive() {
        return this.isactive;
    }

    public void setIsactive(BigDecimal isactive) {
        this.isactive = isactive;
    }

    public BigDecimal getIskulisse() {
        return this.iskulisse;
    }

    public void setIskulisse(BigDecimal iskulisse) {
        this.iskulisse = iskulisse;
    }

    public BigDecimal getIsoverview() {
        return this.isoverview;
    }

    public void setIsoverview(BigDecimal isoverview) {
        this.isoverview = isoverview;
    }

    public BigDecimal getLayertypIdFk() {
        return this.layertypIdFk;
    }

    public void setLayertypIdFk(BigDecimal layertypIdFk) {
        this.layertypIdFk = layertypIdFk;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getRO() {
        return this.rO;
    }

    public void setRO(BigDecimal rO) {
        this.rO = rO;
    }

    public BigDecimal getSourceId() {
        return this.sourceId;
    }

    public void setSourceId(BigDecimal sourceId) {
        this.sourceId = sourceId;
    }

    public BigDecimal getSystem() {
        return this.system;
    }

    public void setSystem(BigDecimal system) {
        this.system = system;
    }

    public BigDecimal getUseCompletecache() {
        return this.useCompletecache;
    }

    public void setUseCompletecache(BigDecimal useCompletecache) {
        this.useCompletecache = useCompletecache;
    }

    public String getXmlDef() {
        return this.xmlDef;
    }

    public void setXmlDef(String xmlDef) {
        this.xmlDef = xmlDef;
    }

    public Label getLabel() {
        return this.label;
    }

    public void setLabel(Label label) {
        this.label = label;
    }

    public Symbol getSymbol() {
        return this.symbol;
    }

    public void setSymbol(Symbol symbol) {
        this.symbol = symbol;
    }

    public Tabellen getTable() {
        return this.table;
    }

    public void setTable(Tabellen table) {
        this.table = table;
    }
}

Edit #2: The used DAO-Class. Nothing in it except the type definition for the generics:

public class LayerDao extends AbstractDao<Layer, Long> {

}

Solution

  • Finally i found the mistake. In the AbtractDao constructor i use the pretty common code to determine the class type:

    final ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
    this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
    

    A close look revealed that I tried to use the key object-type genericSuperclass.getActualTypeArguments()[1] instead of the entity object-type genericSuperclass.getActualTypeArguments()[0].

    The correct constructor looks like this now

      @SuppressWarnings("unchecked")
        public AbstractDao() {
            final ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
            this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[0];
        }
    

    and everything works as expected. Sorry for the inconvenience.