ORA-01400 cannot insert null error in one to one relationship - java

i have this code
public void guardarAspirante(AspiranteDTO aspiranteDTO) {
Aspirante aspirante = new Aspirante();
String usuarioMovimiento = AspiranteCN.class.getSimpleName();
Date fecha = new Date();
aspirante.setCodigoAlumno(aspiranteDTO.getCodigoUniversitario());
aspirante.setNombre(aspiranteDTO.getNombre());
aspirante.setApellidoPaterno(aspiranteDTO.getPrimerApellido());
aspirante.setApellidoMaterno(aspiranteDTO.getSegundoApellido());
aspirante.setUsuarioMovimiento(usuarioMovimiento);
aspirante.setFechaMovimiento(fecha);
Solicitud solicitud = new Solicitud(aspirante.getSolicitudId());
solicitud.setAspirante(aspirante);
solicitud.setSolicitudId(aspirante.getSolicitudId());
solicitud.setOfertaId(aspiranteDTO.getOfertaAcademica());
solicitud.setPeriodoId(aspiranteDTO.getPeriodo());
solicitud.setAportacion(aspiranteDTO.getAportacionVoluntaria());
solicitud.setFechaMovimiento(fecha);
solicitud.setUsuarioMovimiento(usuarioMovimiento);
aspirante.setSolicitud(solicitud);
....
aspiranteDAO.persist(aspirante);
}
and this error
Internal Exception: java.sql.SQLException: ORA-01400: cannot insert NULL into ("RPINGRE"."ARE_SOLI"."ARE_SOLI_SOLIASPI_ID")
This is Aspirante Entity (Fragment)
#Entity
#Table(name = "ARE_SOLIASPI", catalog = "", schema = "RPINGRE")
public class Aspirante implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(sequenceName = "RPINGRE.SQ_ARE_SOLIASPI",
name = "RPINGRE.SQ_ARE_SOLIASPI",
initialValue = 1,
allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RPINGRE.SQ_ARE_SOLIASPI")
#Id
#Basic(optional = false)
#Column(name = "ARE_SOLIASPI_ID")
private Long solicitudId;
#Basic(optional = false)
#Column(name = "ARE_SOLIASPI_CODIGO")
private String codigoAlumno;
#Basic(optional = false)
#Column(name = "ARE_SOLIASPI_NOMBRE")
private String nombre;
#Column(name = "ARE_SOLIASPI_APE_PATERNO")
private String apellidoPaterno;
#Column(name = "ARE_SOLIASPI_APE_MATERNO")
private String apellidoMaterno;
#Basic(optional = false)
#Column(name = "ARE_SOLIASPI_MOV_USUARIO")
private String usuarioMovimiento;
#Basic(optional = false)
#Column(name = "ARE_SOLIASPI_MOV_FECHA")
#Temporal(TemporalType.TIMESTAMP)
private Date fechaMovimiento;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "aspirante", fetch = FetchType.LAZY)
private Solicitud solicitud;
and Solicitud Entity (Fragment)
#Entity
#Table(name = "ARE_SOLI", catalog = "", schema = "RPINGRE")
public class Solicitud implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "ARE_SOLI_SOLIASPI_ID")
private Long solicitudId;
#Basic(optional = false)
#Column(name = "ARE_SOLI_MOV_USUARIO")
private String usuarioMovimiento;
#Basic(optional = false)
#Column(name = "ARE_SOLI_MOV_FECHA")
#Temporal(TemporalType.TIMESTAMP)
private Date fechaMovimiento;
#Column(name = "ARE_SOLI_PERIODO_ID")
private String periodoId;
#Column(name = "ARE_SOLI_OFERTA_ID")
private Long ofertaId;
#Column(name = "ARE_SOLI_APORTACION")
private Long aportacion;
#JoinColumn(name = "ARE_SOLI_SOLIASPI_ID", referencedColumnName = "ARE_SOLIASPI_ID", insertable = false, updatable = false, nullable = false)
#OneToOne(optional = false, fetch = FetchType.LAZY)
private Aspirante aspirante;
.....
}

try changing GenerationType.SEQUENCE to GenerationType.Auto.

The ORA-01400 error says that you are trying to insert a NULL into a column defined as NOT NULL.
I suggest you ether set a default value on the column or have your code make sure the NOT NULL columns have data before you do the INSERT (or use an NVL function in your INSERT statement)

Related

How to ignore update or insert join if NULL value

I have a entity bean with a relation #ManyToOne that is in join on one column.
#Entity
#Table(name = "work_order")
public class WorkOrder implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#NotNull
#Column(name = "id_order", nullable = false)
private String idOrder;
#Column(name = "description")
private String description;
#Enumerated(EnumType.STRING)
#Column(name = "status")
private StatusOrder status;
#Column(name = "creation_date")
private Instant creationDate;
#Column(name = "closing_date")
private Instant closingDate;
#Column(name = "client_id")
private Long clientId;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) #NotFound (action = NotFoundAction.IGNORE)
#Fetch(FetchMode.JOIN)
#JoinColumn(name = "account", insertable = false, updatable = false, nullable = true)
private AnagraficaClienti account;
And the second Entity
#Entity
#Table(name = "es_account")
public class AnagraficaClienti implements Serializable {
private static final long serialVersionUID = 1L;
// da rimettere a #NotNull
#Column(name = "fk_cod_azienda", nullable = true)
private String fk_cod_azienda;
#Id
#NotNull
#Column(name = "account", nullable = false)
private String account;
// da rimettere a #NotNull
#Column(name = "tipo_cli_for", nullable = true)
private String tipoClienteFornitore;
#Column(name = "tipo_account", nullable = true)
private String tipoAccount;
....
The "es_account" table has three not nullable primary key(fk_cod_azienda, account, tipo_cli_for) and the relation with the "work_order" table is by account column.
My problem is that sometimes it is possible that the user insert or update WorkOrder with a null account value and that is not avoid by AnagraficaClienti entity because it expects a non null(and not duplicate) value.
Are there any possible way to bypass the join with AnagraficaClienti when account is null?
In my point of view, #ManyToOne is violate OOP design principle due to the creation of redundant relation. Instead, i always create a #OneToMany relation with a list of related entities. To specify the relation as nullable, just add the nullable=true property in #JoinColumn. With #ManyToOne, you must specify property optional=true. Lets try and see if it works.
WorkOrder
#Entity
#Table(name = "work_order")
public class WorkOrder implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#NotNull
#Column(name = "id_order", nullable = false)
private String idOrder;
#Column(name = "description")
private String description;
#Enumerated(EnumType.STRING)
#Column(name = "status")
private StatusOrder status;
#Column(name = "creation_date")
private Instant creationDate;
#Column(name = "closing_date")
private Instant closingDate;
#Column(name = "client_id")
private Long clientId;
AnagraficaClienti
#Entity
#Table(name = "es_account")
public class AnagraficaClienti implements Serializable {
private static final long serialVersionUID = 1L;
// da rimettere a #NotNull
#Column(name = "fk_cod_azienda", nullable = true)
private String fk_cod_azienda;
#Id
#NotNull
#Column(name = "account", nullable = false)
private String account;
// da rimettere a #NotNull
#Column(name = "tipo_cli_for", nullable = true)
private String tipoClienteFornitore;
#Column(name = "tipo_account", nullable = true)
private String tipoAccount;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
#JoinColumn(name = "account", nullable = true)
private List<WorkOrder> workOrders;
When you want to insert the work order to the database:
workOrderRepository.save(workOrder);
When you want to create the relationship:
AnagraficaClienti client = anagraficaClientiRepository.findById(...);
client.getWorkOrders().add(newWorkOrder);

Is it okay for two columns to be created in a bidirectional relationship?

Is it possible to create one column for bi-directional relationship?
My Entities:
#Entity
#Table(name = "subscription")
#Proxy(lazy = false)
public class Subscription {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "subscription_id")
private long id;
#Column(name = "userid", nullable = false)
private String userId;
#Column(name = "saledate", nullable = false)
#Temporal(TemporalType.DATE)
private Date saleDate;
#Column(name = "finishdate", nullable = false)
#Temporal(TemporalType.DATE)
private Date finishDate;
#Column(name = "price", nullable = false)
private long price;
#Column(name = "description", nullable = false)
private String description;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "subscription")
private List<VisitDate> visitDates = new ArrayList<>();
}
#Entity
#Table(name="visitdate")
public class VisitDate {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
private long id;
private long subscription;
#Column(name = "date", nullable = false)
#Temporal(TemporalType.DATE)
private Date date;
#ManyToOne
#JoinColumn(name="subscription_id")
private Subscription associatedSub;
}
Now I see two columns in the database and little bit confused.
I don't want to save the same data but want to display a report about how many users visit on some day.
Update:
You are not required to create a separate field "subscription" in VisitDate class. Hibernate will automatically create a field to store subscription id. The code needs to be slightly changed.
#Entity
#Table(name = "subscription")
public class Subscription {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "subscription_id")
private long id;
#Column(name = "userid", nullable = false)
private String userId;
#Column(name = "saledate", nullable = false)
#Temporal(TemporalType.DATE)
private Date saleDate;
#Column(name = "finishdate", nullable = false)
#Temporal(TemporalType.DATE)
private Date finishDate;
#Column(name = "price", nullable = false)
private long price;
#Column(name = "description", nullable = false)
private String description;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "associatedSub")
private List<VisitDate> visitDates = new ArrayList<>();
}
Notice, that I have changed the mappedBy property to point at associatedSub in the above class.
#Entity
#Table(name="visitdate")
public class VisitDate {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "date", nullable = false)
#Temporal(TemporalType.DATE)
private Date date;
#ManyToOne
#JoinColumn(name="subscription_id")
private Subscription associatedSub;
}
You can use Uni-Directional relationship for the same purpose. You just need to add a list/set of Visits for a particular subscription, You don't have to create a list of subscription for a particular visit.
for reference Visit [Java JPA] :(https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Undirectional_OneToMany.2C_No_Inverse_ManyToOne.2C_No_Join_Table_.28JPA_2.0_ONLY.29)!
#Entity
#Table(name = "subscription")
#Proxy(lazy = false)
public class Subscription {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "subscription_id")
private long id;
#Column(name = "userid", nullable = false)
private String userId;
#Column(name = "saledate", nullable = false)
#Temporal(TemporalType.DATE)
private Date saleDate;
#Column(name = "finishdate", nullable = false)
#Temporal(TemporalType.DATE)
private Date finishDate;
#Column(name = "price", nullable = false)
private long price;
#Column(name = "description", nullable = false)
private String description;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "subscription")
private List<VisitDate> visitDates = new ArrayList<>();
}
#Entity
#Table(name="visitdate")
public class VisitDate {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
private long id;
private long subscription;
#Column(name = "date", nullable = false)
#Temporal(TemporalType.DATE)
private Date date;
}

How to negate several predicates

I have two entities
#Entity
#Table(name = SIGNAL")
public class TradingSignal {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", nullable = false, unique = true)
private int id;
#Column(name = "SIGNAL_ID")
private int signalId;
#Column(name = "TICKER", length = 6)
private String ticker;
#OneToMany(cascade = CascadeType.ALL)
private Set<TsUsed> tsUsedSet;
}
and
#Entity
#Table(name = "TS_USED")
public class TsUsed {
#Id
#Column(name = "FILTER_ID", nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private int filterId;
#Column(name = "USER_ID_LSB")
private long userIdLsb;
#Column(name = "USER_ID_MSB")
private long userIdMsb;
#Column(name = "VISIBLE")
private boolean visible;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "ID", nullable = false)
private TradingSignal tradingSignal;
}
How can I find all TradingSignals where TsUsed.userIdLsb and TsUsed.userIdMsb are not exists in tsUsedSet?
Can't create valid predicate.
This code not work for me
Join<TradingSignal, TsUsed> tsUsed = getTsUsedJoin(root);
Predicate predicateUserIdLsb = builder.equal(tsUsed.get("userIdLsb"), userId.getLeastSignificantBits());
Predicate predicateUserIdMsb = builder.equal(tsUsed.get("userIdMsb"), userId.getMostSignificantBits());
Predicate predicateInvisible = builder.isFalse(tsUsed.get("visible"));
Predicate notInvisibleForUser = builder.and(predicateUserIdLsb, predicateUserIdMsb, predicateInvisible).not();

Mysql - JPA no insert into thrid table Many to Many

I have Many-To-Many relation in my project, i can write in my two Entities table, the relational table does not get anything written.
EspecificacionEscenario Class:
public class EspecificacionEscenario implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idespecificacionEscenario")
private Integer idespecificacionEscenario;
#Column(name = "codigo")
private String codigo;
#Column(name = "fecha")
#Temporal(TemporalType.TIMESTAMP)
private Date fecha;
#Column(name = "nombreProceso")
private String nombreProceso;
#Column(name = "nombreEscenario")
private String nombreEscenario;
#Column(name = "objetivoEscenario")
private String objetivoEscenario;
#Column(name = "lugarEscenario")
private String lugarEscenario;
#Column(name = "recursoEscenario")
private String recursoEscenario;
#Column(name = "restriccionEscenario")
private String restriccionEscenario;
#Column(name = "actoresEscenario")
private String actoresEscenario;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Elicitacion> elicitacionList;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Episodio> episodioList;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Educcion> educcionList;
Episodio class:
public class Episodio implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idepisodio")
private Integer idepisodio;
#Column(name = "codigo")
private String codigo;
#Column(name = "objetivoEpisodio")
private String objetivoEpisodio;
#Column(name = "descripcionEpisodio")
private String descripcionEpisodio;
#Column(name = "recursosEpisodio")
private String recursosEpisodio;
#Column(name = "restriccionEpisodio")
private String restriccionEpisodio;
#Column(name = "actor")
private String actor;
#JoinTable(name = "especificacionEscenarioEpisodio", joinColumns = {
#JoinColumn(name = "idepisodio", referencedColumnName = "idepisodio")}, inverseJoinColumns = {
#JoinColumn(name = "idespecificacionEscenario", referencedColumnName = "idespecificacionEscenario")})
#ManyToMany(fetch = FetchType.LAZY)
private List<EspecificacionEscenario> especificacionEscenarioList;
Main code:
public static void main(String[] args) {
EpisodioDao episodioDao = new EpisodioDao();
EspecificacionEscenarioDao escenarioDao = new EspecificacionEscenarioDao();
Episodio episodio = new Episodio();
episodio.setCodigo("e01");
episodio.setDescripcionEpisodio("descripcion episodio");
EspecificacionEscenario ee = new EspecificacionEscenario();
ee.setCodigo("ee-01");
List<Episodio> listaE = new ArrayList<>();
listaE.add(episodio);
ee.setEpisodioList(listaE);
episodioDao.registrarEpisodio(episodio);
System.exit(0);
}
when doing the persistence in the entities the information is saved automatically, but in the table third table it does not insert the primary keys.
I have added CascadeType.ALL on Episodio as it is the owner of this relation.
Following code may help you. I have tested with spring data jpa.
#Setter
#Getter
#Entity
public class Episodio implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idepisodio")
private Integer idepisodio;
#Column(name = "codigo")
private String codigo;
#Column(name = "objetivoEpisodio")
private String objetivoEpisodio;
#Column(name = "descripcionEpisodio")
private String descripcionEpisodio;
#Column(name = "recursosEpisodio")
private String recursosEpisodio;
#Column(name = "restriccionEpisodio")
private String restriccionEpisodio;
#Column(name = "actor")
private String actor;
#JoinTable(name = "especificacionEscenarioEpisodio",
joinColumns = {
#JoinColumn(name = "idepisodio", referencedColumnName = "idepisodio")},
inverseJoinColumns = {
#JoinColumn(name = "idespecificacionEscenario", referencedColumnName = "idespecificacionEscenario")})
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<EspecificacionEscenario> especificacionEscenarioList;
}
#Setter
#Getter
#Entity
public class EspecificacionEscenario implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idespecificacionEscenario")
private Integer idespecificacionEscenario;
#Column(name = "codigo")
private String codigo;
#Column(name = "fecha")
#Temporal(TemporalType.TIMESTAMP)
private Date fecha;
#Column(name = "nombreProceso")
private String nombreProceso;
#Column(name = "nombreEscenario")
private String nombreEscenario;
#Column(name = "objetivoEscenario")
private String objetivoEscenario;
#Column(name = "lugarEscenario")
private String lugarEscenario;
#Column(name = "recursoEscenario")
private String recursoEscenario;
#Column(name = "restriccionEscenario")
private String restriccionEscenario;
#Column(name = "actoresEscenario")
private String actoresEscenario;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Episodio> episodioList;
}
EspecificacionEscenario especificacionEscenario = new EspecificacionEscenario();
especificacionEscenario.setCodigo("ee-01");
List<EspecificacionEscenario> especificacionEscenarios = new ArrayList<>();
especificacionEscenarios.add(especificacionEscenario);
Episodio episodio = new Episodio();
episodio.setCodigo("e01");
episodio.setDescripcionEpisodio("descripcion episodio");
episodio.setEspecificacionEscenarioList(especificacionEscenarios);
episodioRepo.save(episodio);

JPA - Issues removing child entities on bidirectional mapping

I need to remove a child entity called "SystemParamater" based on the it´s id.
What i was trying to do:
- Begin Tran
SystemParameter param EntityManager.find(SystemParameter.class,<paremeter.id>)
EntityManager.remove(param)
-Commit tran
But the entity was not removed.
What´s the correct way to remove a child entity?
Below, you could find my entities:
SystemParameter:
#Entity
#Table(name = "system_parameters")
#Cacheab le
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SystemParameter extends BasicEntity {
private static final long serialVersionUID = -6416605270912358340L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "paramName", length = 50, nullable = false)
private String paramName;
#Column(name = "paramValue", length = 255, nullable = false)
private String paramValue;
#Column(name = "encrypted", nullable = false)
#Type(type = "yes_no")
private Boolean encrypted = Boolean.FALSE;
#ManyToOne
#JoinColumn(name = "groupId", nullable = false)
private SystemParameterGroup parameterGroup;
}
SystemParameterGroup:
#Entity
#Table(name = "system_parameter_groups", uniqueConstraints = { #UniqueConstraint(columnNames = { "searchKey" }) })
#Cacheable
public class SystemParameterGroup extends BasicEntity {
private static final long serialVersionUID = -1762633144642103487L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name", length = 50, nullable = false)
private String name;
/**
* Description.
*/
#Column(name = "description", length = 255, nullable = false)
private String description;
/**
* Search key.
*/
#Column(name = "searchKey", length = 50, nullable = false)
private String searchKey;
/**
* System parameter list.
*/
#OneToMany(fetch = FetchType.EAGER, mappedBy = "parameterGroup", cascade = CascadeType.ALL, orphanRemoval = true)
#OrderBy("paramName")
private List<SystemParameter> systemParameterList;
}
You have to remove the SystemParameter entity also from the SystemParameterGroup's list of SystemParameter:
systemParameterGroup.getSystemParameterList().remove(systemParameter);
This issue is related to this one.

Categories

Resources