JPA Hibernate Classe intermediária com problemas ao persistir

2 respostas
J

Bem estou utilizando JPA com Spring, e estou com um problema no momento de executar o merge.

Tenho uma classe Task uma classe WorkflowField e uma intermediária TaskFieldValue:

`

@Entity
@Table(name = "tarefa", )
public class Task
extends Identity
implements Serializable {

    @OneToMany(mappedBy="task", cascade=CascadeType.ALL)
    private List<StageTaskUser> stageTaskUsers;
    ...
}

@Entity
@Table(name = "tarefa_campo_valor")
public class TaskFieldValue
implements Serializable {

    @Id@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ref_tarefa", nullable = false, updatable = false, insertable = false)
    private Task task;

    @Id@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ref_campo", nullable = false, updatable = false, insertable = false)
    private WorkflowField field;
    ...}

@Entity
@Table(name="campo_workflow")
public class WorkflowField
extends Identity
implements Serializable {
    ...
}

`

Setei em meu objeto Task uma lista de TaskFieldValue:

`

Task task = //Vem do banco
WorkflowField field1 = //Vem do banco
WorkflowField field2 = //Vem do banco 

TaskFieldValue tfv1 = new TaskFieldValue();
TaskFieldValue tfv2 = new TaskFieldValue();
tfv1.setTask(task);
tfv1.setField(field1);
tfv2.setTask(task);
tfv2.setField(field2);

List<TaskFieldValue> l = new ArrayList<TaskFieldValue>();
l.add(tfv1);
l.add(tfv2);

task.setTaskFieldValues(l);`

Classe que salva no DB:

`

@Repository
public class TaskJpaDAO 
implements 
    Serializable,
    TaskDAO {

@PersistenceContext
private EntityManager manager;

@Override
public void update(final Task value) {
    if(manager.contains(value)) {
        manager.persist(value);
    } else {
        manager.merge(value);
    }
}

`

O mesmo acaba caindo no

manager.merge()

Ao invés de funcionar e inserir os valores corretamente para os TaskFieldValue, acaba ocorrendo um erro, como se para cada TaskFieldValues o Task e WorkflowField estivessem nullos, mas debugando percebi que não estão:

Percebam no erro que no insert passa dois null, null que são referentes ao Task (ref_tarefa) e WorkflowField (ref_field):

`

insert into tarefa_campo_valor (valor, ref_tarefa, ref_campo) values (?, ?, ?)

Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "ref_campo" violates not-null constraint
Detalhe: Failing row contains (5, 1, null, null).
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:622)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:472)
at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:429)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 65 more`

Já no debug no momento do merge é possível ver que o Task e WorkflowField não estão nulos.

Se alguém puder ajudar…

2 Respostas

A

Na sua classe TaskFieldValue você colocou updatable = false, insertable = false. Isso diz pro hibernate não inserir nem atualizar dados baseados nesse campo. Normalmente a gente usa quando tem mais de um atributo mapeado para o mesmo campo. Tenta remover isso para ver se o comportamento se corrige.

J

Opa, fiz a alteração e continua o mesmo erro:

`

@Entity
@Table(name = "tarefa_campo_valor")
public class TaskFieldValue implements Serializable {
    private static final long serialVersionUID = -3785074111624497514L;

@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ref_tarefa", nullable = false)
private Task task;

@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ref_campo", nullable = false)
private WorkflowField field;

`

O mais interessante é que se já passo a lista de campos (TaskFieldValue) ao criar a tarefa funciona, claro só que ai é chamado persiste(task) ao invés de merge(task).
At.

Criado 18 de abril de 2016
Ultima resposta 20 de abr. de 2016
Respostas 2
Participantes 2