Um-para-muitos unidirecional Parent-Child ID Cascade Guardar
-
18-09-2019 - |
Pergunta
Ao tentar salvar um ID de minha classe pai em uma classe criança, eu continuo recebendo o erro "ERRO - campo 'parent_id' não tem um valor padrão"
Eu tentei todos os tipos de mapeamentos. Eu estou usando anotações.
Qualquer ajuda sobre isso seria apreciada
Pais:
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name="description")
private String description;
@OneToMany
@Cascade(value= {org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
@JoinColumn(name="parent_id")
private List<Child> children;
Criança:
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name="description")
private String description;
Graças.
Solução
Você deve ter algo de errado em algum outro lugar, porque esses mapeamentos vai funcionar do jeito que são. Elas podem ser melhor, mas eles vão trabalhar. Especificamente, todas as anotações @Column
são redundantes e desnecessários, e como não Sequitor observou, você deve usar a propriedade cascata de @OneToMany
da APP em vez de @Cascade
do Hibernate. Eu criei um exemplo executável com a versão limpa-up do que você postou. Se você tem git e Maven, você pode executá-lo com:
git clone git://github.com/zzantozz/testbed tmp
cd tmp
mvn -q compile exec:java \
-Dexec.mainClass=rds.hibernate.UnidirectionalManyToOneJoinColumn \
-pl hibernate-unidirectional-one-to-many-with-join-column
Ele cria um pai com dois filhos, os salva, e depois carrega-los e imprime o gráfico. A saída é:
Creating parent with two children
Loading saved parent
Parent{description='parent', children=[Child{description='child 2'}, Child{description='child 1'}]}
Outras dicas
A adição tardia no caso de alguém que nunca corre para o mesmo problema.
Esta entidade aqui, quando persistiu usando Hibernate 4.1.8, irá em cascata as FieldChange
entities, mas irá não preencher a coluna de junção:
@Entity
public class Event {
//ID and other fields here
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "event_id")
private List<FieldChange<?>> fields = new ArrayList<FieldChange<?>>();
}
Nem a instrução de inserção definir a coluna event_id
, nem atualizar a entidade inserido após o fato - o nulo event_id
restos ea relação está perdido.
Se, no entanto, a definição @JoinColumn
é alterado da seguinte forma:
@JoinColumn(name = "event_id", nullable = false)
, então a instrução de inserção inclui a coluna event_id
como deveria, e está tudo bem.
Isso só pode ser uma regressão nesta versão particular do Hibernate, mas talvez ajude alguém.
Em seu provedor de JPA caso de persistir objeto filho com seu pai realizar pelo menos três consultas no db. Primeiro dois persistir os objetos por conta própria. O último objeto filho atualização com o pai de referência de chave estrangeira. A segunda consulta falhar, porque você tem uma restrição NOT NULL na coluna de chave estrangeira. Você tem três opções:
- Remover NÃO restrição NULL na chave estrangeira na entidade criança
- Use relação bidirecional
- provedor de Mudança JPA para um que suporta tais casos.
Mude o seu @OneToMany
ao uso @OneToMany(cascade=CascadeType.ALL)
JPA em vez das extensões do Hibernate
O meu palpite é que o @JoinColumn annotation
precisa de um referencedColumnName
atribuído.
@JoinColumn(name = "parent_id", referencedColumnName = "id")