JPA-Persistiendo una relación Unidireccional de Uno a Muchos falla con EclipseLink
Estoy tratando de persistir una relación Unidireccional muy simple de Uno a Muchos, pero EclipseLink (2.3.1) falla.
Clase de servicio (Padre):
@Entity
@Table(name = "tbl_service2")
public class Service implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="service_id")
public long serviceID;
@Column(name="name")
public String name;
@OneToMany(cascade={CascadeType.ALL})
@JoinColumn(name="service_id", referencedColumnName="service_id")
public Set<Parameter> parameters;
}
Clase de parámetro (Hijo):
(Por supuesto, hay un campo de clave foránea" service_id " en la base de datos, que no está representado en la clase, ya que es una relación unidireccional).
@Entity
@Table(name = "tbl_service_parameters2")
public class Parameter implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="param_id")
public long parameterID;
@Column(name="name")
public String name;
}
Y este es el código para la persistencia de entidades:
Service service = new Service();
service.parameters = new HashSet<Parameter>();
service.name = "test";
Parameter param = new Parameter();
param.name = "test";
service.parameters.add(param);
em.persist(service);
em.flush();
Obtengo esta excepción:
Internal Exception: java.sql.SQLException: Field 'service_id' doesn't have a default value
Error Code: 1364
Call: INSERT INTO tbl_service_parameters2 (name) VALUES (?)
bind => [test]
EDITAR: La base de datos field service_id
tiene (y debería tener) restricción not-null, debido a la naturaleza de los datos.
¿Es esto un error o algo está mal en el código?
6 answers
Intente eliminar la restricción not null en el campo service_id de la tabla de parámetros. Eclipselink actualizará la clave foránea para columnas unidireccionales de unión 1:m en una instrucción separada, por lo que deberá deshabilitar o retrasar la comprobación de restricciones. Hacerlo bidireccional permitirá que el campo fp se actualice con el resto de los datos del parámetro.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-06 19:42:31
Use nullable = false
, on @JoinColumn
:
@JoinColumn(name = "service_id", nullable = false)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-11 18:18:49
By default nullable is true on @JoinColumn, while persisting the data in one to many relationship, we need to make nullable as false to avoid data voliation exceptions that occurs at run-time
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-06 14:13:35
Puede cambiar su persistencia para la versión de hibernación
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-20 16:41:18
Pude conseguir que funcione en Oracle mediante el uso de una clave foránea deferible.
Ejemplo:
ALTER TABLE my_table ADD CONSTRAINT my_constraint_name FOREIGN KEY (my_table_column) REFERENCES foreign_key_table (foreign_key_table_column) DEFERRABLE INITIALLY DEFERRED
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-15 12:32:51
Como he averiguado, en tales casos, la clave foránea se rellena en una declaración separada. En mi ejemplo, usé Address
entidad con customer_id
como clave foránea.
2014-07-08T20:51:12.752+0300|FINE: INSERT INTO ADDRESS (address_id, street, city, region) VALUES (?, ?, ?, ?)
bind => [10, foo, foo, foo]
2014-07-08T20:51:12.753+0300|FINEST: Execute query InsertObjectQuery(ua.test.customer.Address@28cef39d)
2014-07-08T20:51:12.757+0300|FINEST: Execute query DataModifyQuery(sql="UPDATE ADDRESS SET customer_id = ? WHERE (address_id = ?)")
2014-07-08T20:51:12.757+0300|FINE: UPDATE ADDRESS SET customer_id = ? WHERE (address_id = ?)
bind => [151, 10]
Por lo tanto, tener @JoinColumn
con nullable=true
causa un error.
Como alternativa, puede usar @OneToMany (..., orphanRemoval = true, ...)
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-08 18:02:27