Нет конструктора по умолчанию для объекта для внутреннего класса в Hibernate
У меня есть два класса. Один из них - класс сущности, другой - составной класс ключей.
Выполняется следующий код.
@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();
}
Если я попытаюсь найти
from Supply where merchandise_id=%d and supplier_id=%d
Hibernate выдаст исключение, а именно:
No default constructor for entity: com.entity.Supply$Id; nested exception is org.hibernate.InstantiationException: No default constructor for entity: com.entity.Supply$Id
Однако я обнаружил, что если я изменил класс Id на статический. Все будет хорошо.
Мне просто интересно, как все это может случиться.
Ответы
Ответ 1
Если класс не является static
, для экземпляра требуется экземпляр внешнего класса, поэтому конструктор по умолчанию не будет. Вам нужно будет использовать синтаксис, похожий на:
new Supply().new Id();
Если класс Id
static
, вы можете просто вызвать:
new Id();
Ответ 2
Я всегда добавляю в класс пустой защищенный конструктор для решения этой проблемы следующим образом:
protected Classname(){}
В вашем случае это будет выглядеть так:
protected Id(){}
Ответ 3
Если класс не статичен, ему потребуется внешний экземпляр класса. Итак, я думаю, сгенерированный конструктор в этом случае будет иметь неявный параметр для внешнего класса.
Update
Как я и ожидал:
$ javap -classpath . Supply\$Id
Compiled from "Supply.java"
class Supply$Id extends java.lang.Object{
final Supply this$0;
Supply$Id(Supply);
}
Ответ 4
Если вы используете Spring, добавление аннотации @NoArgsConstructor решит отсутствующую ошибку конструктора по умолчанию.