web-dev-qa-db-fra.com

Aucun constructeur par défaut pour l'entité pour la classe interne dans Hibernate

J'ai deux classes. L'une est la classe d'entité, l'autre sert de classe de clé composite.

Le code est le suivant.

@Entity
public class Supply {

    @Embeddable
    class Id implements Serializable {

        @Column(name = "supplier_id")
        private long supplierId;
        @Column(name = "merchandise_id")
        private long merchandiseId;

        public Id() {
        }

        public Id(long sId, long mId) {
            this.supplierId = sId;
            this.merchandiseId = mId;
        }
    }

    @EmbeddedId
    private Id id = new Id();
}

Si j'utilise, essayez de trouver

from Supply where merchandise_id=%d and supplier_id=%d

Hibernate lèvera une exception, à savoir:

No default constructor for entity: com.entity.Supply$Id; nested exception is org.hibernate.InstantiationException: No default constructor for entity: com.entity.Supply$Id

Cependant, j'ai trouvé que si je change la classe Id en statique. Tout ira bien.

Je suis simplement curieux de savoir comment tout cela peut arriver.

33
xiaohan2012

Si la classe n'est pas static, elle nécessite une instance de la classe externe pour être instanciée - il n'y aura donc pas de constructeur par défaut. Vous devez utiliser une syntaxe similaire à:

new Supply().new Id();

Si la classe Id est static, vous pouvez simplement appeler:

new Id();
44
Bohemian

J'ajoute toujours un constructeur protégé vide à la classe pour résoudre ce problème comme suit:

protected Classname(){}

Dans votre cas, cela ressemblerait à ceci:

protected Id(){}
9
Ben

Si la classe n'est pas statique, il faudra que l'instance de classe externe existe. Donc, je pense que le constructeur généré dans ce cas aura un paramètre implicite pour la classe externe.


Mettre à jour

Comme je l'attendais:

$ javap -classpath . Supply\$Id
Compiled from "Supply.Java"
class Supply$Id extends Java.lang.Object{
    final Supply this$0;
    Supply$Id(Supply);
}
0
Alex Gitelman