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.
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();
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(){}
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);
}