Foreign key value not inserting in database: Cannot insert Null in column - orm

I am migrating client application from Hibernate to EclipseLink. But it is not inserting value for foreign key when calling persist method on student entity. Database is oracle. There is Many to one relation between Address and Student.
Also in generated SQL the foreign key column is not present.
#Entity
#Table(name = "Student", schema = "Student_DB")
#SequenceGenerator(name = "studentSeq", sequenceName = "Student_SEQ", schema = "Student_DB", allocationSize = 1)
public class StudentEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "studentSeq")
#Column(name = "S_ID")
private BigDecimal studentID;
#OneToMany(mappedBy = "studentEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "S_ID")
private List<AddressEntity> addresses;
}
addAddress(address){
address.setStudentEntity(this);
#Entity
#Table(name = "Address", schema = "Student_DB")
#SequenceGenerator(name = "AddressSeq", sequenceName = "Address_SEQ", schema = "Student_DB", allocationSize = 1)
public class AddressEntity implements Serializable {
#Id
#Column(name = "A_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AddressSeq")
private long addressID;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "S_ID", referencedColumnName = "S_ID", insertable = false, updatable = false, nullable = false)
private StudentEntity studentEntity;
}
*
> [EL Fine]: sql: 2019-06-25
> 18:39:00.895--ClientSession(1656550367)--Connection(-872205654)--INSERT
> INTO Student_DB.Student (S_ID, ...) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,
> ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) bind => [24 parameters
> bound] [EL Fine]: sql: 2019-06-25
> 18:39:00.946--ClientSession(1656550367)--Connection(-872205654)--INSERT
> INTO Student_DB.Address (A_ID, CO...) VALUES (?, ?, ?, ?, ?) bind =>
> [5 parameters bound] [EL Fine]: sql: 2019-06-25
> 18:39:00.954--ClientSession(1656550367)--SELECT 1 FROM DUAL [EL
> Warning]: 2019-06-25 18:39:00.955--UnitOfWork(-922357549)--Exception
> [EclipseLink-4002] (Eclipse Persistence Services -
> 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException Internal
> Exception: java.sql.SQLIntegrityConstraintViolationException:
> ORA-01400: cannot insert NULL into ("Student_DB"."Address"."S_ID")
*

The correct mapping would look like:
#Entity
#Table(name = "Student", schema = "Student_DB")
#SequenceGenerator(name = "studentSeq", sequenceName = "Student_SEQ", schema = "Student_DB", allocationSize = 1)
public class StudentEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "studentSeq")
#Column(name = "S_ID")
private BigDecimal studentID;
#OneToMany(mappedBy = "studentEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<AddressEntity> addresses;
}
#Entity
#Table(name = "Address", schema = "Student_DB")
#SequenceGenerator(name = "AddressSeq", sequenceName = "Address_SEQ", schema = "Student_DB", allocationSize = 1)
public class AddressEntity implements Serializable {
#Id
#Column(name = "A_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AddressSeq")
private long addressID;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "S_ID", referencedColumnName = "S_ID", nullable = false)
private StudentEntity studentEntity;
}

Related

SQLIntegrityConstraintViolationException -> Column "name" can not be null INTRESTING

So, i create Entity in my DB from CommandLineRunner, everything okay.
Then i create some controller one of them give me next Exception, when i going to update my Entity ->
***java.sql.SQLIntegrityConstraintViolationException: Column 'name' cannot be null***
Controller
#PostMapping ("/update")
public String update (Instructor instructor) {
instructorService.updateInstructor(instructor);
return "redirect:/instructors/index";
}
Entity
#Entity
#Table (name = "Instructor")
public class Instructor {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column (name = "instructor_id", nullable = false)
private Long instructorId;
#Basic
#Column (name = "name", nullable = false, length = 45)
private String firstName;
#Basic
#Column (name = "lastName", nullable = false, length = 45)
private String lastName;
#Basic
#Column (name = "summary", nullable = false, length = 45)
private String instructorSummary;
#OneToMany (mappedBy = "instructor", fetch = FetchType.LAZY)
private Set <Course> courses = new HashSet<>();
#OneToOne (cascade = CascadeType.REMOVE)
#JoinColumn (name = "user_id", referencedColumnName = "user_id", nullable = false)
private User user;
When i delete (nullable=false) everything work by Entity does not appear in DB
Instructor Service
Instructor updateInstructor (Instructor instructor);
InstructorImpl
#Override
public Instructor updateInstructor(Instructor instructor) {
return instructorDao.save(instructor);
}
DaoClass only extend JpaRepository
Update: here are the logs
Hibernate: update instructor set name=?, summary=?, last_name=?,
user_id=? where instructor_id=? 2023-01-13T14:41:40.545+02:00 WARN
4176 --- [nio-8071-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper :
SQL Error: 1048, SQLState: 23000 2023-01-13T14:41:40.545+02:00 ERROR
4176 --- [nio-8071-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper :
Column 'name' cannot be null 2023-01-13T14:41:40.551+02:00 ERROR 4176
--- [nio-8071-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path
[] threw exception [Request processing failed:
org.springframework.dao.DataIntegrityViolationException: could not
execute statement; SQL [n/a]; constraint [null]] with root cause

Referential integrity constraint violation (CAST( AS BIGINT))

I am creating a database of items and have been trying to assign multiple database entities to a single item however I am struggling to get past an error I keep having. I am unsure what I am doing wrong can someone help?
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKKPIB0GWXM6UFS3SJJ2NCI64AR: PUBLIC.FEATURES FOREIGN KEY(ITEM_ID) REFERENCES PUBLIC.ITEM(ITEM_ID) (CAST(1020 AS BIGINT))"; SQL statement: INSERT INTO FEATURES(FEATURE_ID, ITEM_ID) VALUES(101, 1020), (102,1021), (103,1021), (104,1021)
Item.java
#Entity
#Table(name="item")
public class Item {
#Id
#Column(name = "item_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#Enumerated(EnumType.STRING)
private ItemType itemtype;
private int weight;
private int recovers;
private int priority;
private String desc;
#OneToMany(mappedBy = "item")
private List<Feature> features;
}
Feature.java
#Entity
#Table(name = "features")
public class Feature {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long feature_id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "item_id", insertable = false, updatable = false)
#JsonIgnore
private Item item;
}
data.sql
INSERT INTO SPELLS(SPELL_ID, ITEM_ID)
VALUES(101, 1020),
(102, 1021),
(103, 1021),
(104, 1021)
;
INSERT INTO ITEM(ITEM_ID, NAME, ITEMTYPE, WEIGHT, RECOVERS, PRIORITY, DESC)
VALUES (1010,'Hunting Knife','DAGGER',1,5,3,''),
(1011,'Relic Sword','SWORD',3,10,3,''),
(1012,'Relic Spear','SPEAR',3,8,3, ''),
(1013,'Relic Axe','AXE',4,12,3, ''),
(1014,'Old Club','MACE',4,10,3,''),
(1015,'Crooked Stick','STAFF',2,3,3,''),
(1016,'Training Bow','BOW',2,20,4,''),
(1017,'Training Crossbow','CROSSBOW',2,20,4,''),
(1018,'Grass Sling','SLING',2,20,4,''),
(1019,'Wooden Shield','SHIELD',4,20,4,''),
(1020,'Poison wand','WAND', 1,0,4,''),
(1021,'Mushroom staff','STAFF',2,3,3,'')
;

Hibernate query exception:cannot dereference scalar collection element

I am getting following error after starting my spring application:
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: cannot dereference scalar collection element: metadata_descriptor_id [SELECT d FROM com.org.entity.documents.Document d INNER JOIN d.documentMetadata md ON md.document_id = d.id WHERE (md.metadata_descriptor_id.id NOT IN (:documentMetadataId))]
Here is my Document class:
#Entity
#Table(name = "documents")
public class Document {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "name", nullable = false, unique = true)
private String name;
#Column(name = "archived", nullable = false)
private boolean archived;
#Column(name = "creation_date", nullable = false)
private Instant creationDate;
#Column(name = "file_text_processing_status", nullable = false)
#Enumerated(EnumType.STRING)
private FileTextProcessingStatus fileTextProcessingStatus;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "template_file_id", referencedColumnName = "id")
private TemplateFile templateFile;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "state_descriptor_id", referencedColumnName = "id")
private StateDescriptor stateDescriptor;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "user_id", referencedColumnName = "id")
private UserEntity user;
#ElementCollection(targetClass = String.class)
#Column(name = "tag", nullable = false)
#CollectionTable(name = "document_tags", joinColumns = #JoinColumn(name = "document_id"))
private Set<String> tags = new HashSet<>();
#ElementCollection
#CollectionTable(name = "document_metadata", joinColumns = {
#JoinColumn(name = "document_id", referencedColumnName = "id")})
#MapKeyJoinColumn(name = "metadata_descriptor_id", referencedColumnName = "id")
#Column(name = "value", nullable = false)
private Map<MetadataDescriptor, String> documentMetadata = new HashMap<>();
#OneToMany(mappedBy = "document", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<DocumentFileVersion> documentVersions = new HashSet<>();`enter code here`
And here is Repository method that fails:
#Lock(LockModeType.PESSIMISTIC_WRITE)
#Query(value = "SELECT d FROM Document d INNER JOIN d.documentMetadata md ON md.document_id = d.id"
+ " WHERE (md.metadata_descriptor_id NOT IN (:documentMetadataId))")
List<Document> findAllByDocumentRequiredMetadataNotSet(long documentMetadataId);
I have seen an answer for similar question here: getting Caused by: org.hibernate.QueryException: cannot dereference scalar collection element: roles
But it's not helpful in my case. I will be very glad for any suggestions.
The type of md is String this is why you see an error. What you need is something like this:
#Lock(LockModeType.PESSIMISTIC_WRITE)
#Query(value = "SELECT d FROM Document d INNER JOIN d.documentMetadata md WHERE (KEY(md).id NOT IN (:documentMetadataId))")
List<Document> findAllByDocumentRequiredMetadataNotSet(long documentMetadataId);
You also had a ON clause which is no necessary/wrong. I think you should read into HQL/JPQL first as you don't seem to understand that a join of an association, will add the join predicate in the SQL automatically.
Note though, that the syntax KEY(..).id is only supported in newer Hibernate versions, so you might have to update.

unable to update objects of one to one relation in hibernate

I have relation as shown bellow:
#Entity
#Table(name = "ORDER_", catalog = "smartorder")
public class Order implements Serializable {
/**
* serial version id
*/
private static final long serialVersionUID = 13875615L;
#Id
#Column(name = "ORDER_ID", unique = true, nullable = false)
#SequenceGenerator(name = "ORDER_ID_GEN", sequenceName = "ORDER_ID_SEQ")
#GeneratedValue(generator = "ORDER_ID_GEN")
private long orderId;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "INVOICE_ID", referencedColumnName = "INVOICE_ID")
private Invoice invoice;
// setters and getters
}
#Entity
#Table(name = "INVOICE_")
public class Invoice implements Serializable {
/**
* serial version id
*/
private static final long serialVersionUID = 13875612L;
#Id
#Column(name = "INVOICE_ID", unique = true, nullable = false)
#SequenceGenerator(name = "INVOICE_ID_GEN", sequenceName = "INVOICE_ID_SEQ")
#GeneratedValue(generator = "INVOICE_ID_GEN")
private int invoiceId;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "ORDER_ID", referencedColumnName = "ORDER_ID")
private Order order;
#Column(name = "SUB_TOTAL", precision = 6, nullable = false)
private double subTotal;
#Column(name = "SERVICE_TAX", precision = 6, nullable = false)
private double serviceTax;
#Column(name = "VAT", precision = 6, nullable = false)
private double vat;
#Column(name = "SURCHAARGE", precision = 6, nullable = false)
private double surChaarge;
#Column(name = "GRAND_TOTAL", precision = 6, nullable = false)
private double grandTotal;
//setters and getters
}
I am able to save the records properly. But when i am trying to update orders objects by setting invoice object to order object then the order object is nor persisting only invoice object is persisting.
Order o = getSession().load(Order.class,1L);
o.setInvoice(new Invoice(.........));
getSession().update(o);
in console I am able to see one SQL statement only,
insert into INVOICE_ (DISCOUNT, GRAND_TOTAL, ORDER_ID, ROUNDING, SERVICE_TAX, SUB_TOTAL, SURCHAARGE, VAT) values (?, ?, ?, ?, ?, ?, ?, ?)
Invoice Id is not getting update in Order table :(
Can anyone suggest whats the issue is.
Thanks in advance.....
This may depend on your unusual design.
With INVOICE_ID in ORDR_ and ORDER_ID in INVOICE_ you have both tables at the same time as parent and child of each other.
If your database uses foreign keys deleting and inserting will be hard.
You should use one type/table as parent, (e. g. Order, because it's normaly first) and the other as child (order_id will be in invoice_ table).
In your object model you can have both directions (see first example of http://docs.oracle.com/javaee/6/api/javax/persistence/OneToOne.html)
The issue is incorrect scenario in which you used your Entities/Tables and the one-to-one mapping style. The concept of One-To-One does not corresponed with your current design of both tables and entities.
Please, try to read more about one-to-one here: The concept for one-to-one mapping. Explain the mapping
And mostly take a deep look here: Hibernate – One-to-One example (Annotation), where you can find examples of the one-to-one mapping.
If you really would like to continue with one-to-one mapping you have to:
Remove the "INVOICE_ID" column from the "INVOICE_" table (surprising but a fact)
make the "ORDER_ID" column in the "INVOICE_" table as a primary key (another fact)
change the mapping of the Invoice entity to be more submissive (driven by Order entity)
Example of changes of the Invoice mapping:
// just a draft, to give you idea about the
// "submissive" side mapping.
// All the ID stuff of the Invoice is driven by its
// "Master" - Order
#GenericGenerator(name = "generator", strategy = "foreign",
parameters = #Parameter(name = "property", value = "order"))
#Id
#GeneratedValue(generator = "generator")
#Column(name = "ORDER_ID", unique = true, nullable = false)
public Integer getOrderId() {
return this.orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
#OneToOne(fetch = FetchType.LAZY)
#PrimaryKeyJoinColumn
public Order getOrder() {
return this.order;
}
Please, take it as a draft, to show how different the one-to-one concept is.

java.lang.IllegalArgumentException with toplink and JPA

I've a problem with JPA, whenever execute this query
#NamedQuery(name = "Usuario.getUsuarioIntento", query = "SELECT u.intentos_id FROM Usuario u WHERE u.username = :username and u.borrado = 0")
i get this error:
java.lang.IllegalArgumentException: NamedQuery of name: Usuario.getUsuarioIntento not found.
But if i execute this query
#NamedQuery(name = "Usuario.getUsuarioIntento", query = "SELECT u.id FROM Usuario u WHERE u.username = :username and u.borrado = 0")
Work fine,Why?
My table,Usuario:
MY USER TABLE
i try with other column as 'superusuario','version_jpa' and doesn't work, the only columns that work fine are 'id,'borrado' and 'username'
Class Usuario:
#Temporal(TemporalType.TIMESTAMP)
private Date fechaCreacion;
#Id
#GeneratedValue (strategy=GenerationType.AUTO)
private int id;
#OneToOne(cascade = CascadeType.ALL)
private Password password;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
private List<Password> clavesAntiguas;
#OneToOne
private Persona persona;
private String sessionId;
private String username;
#ManyToOne(cascade = CascadeType.REFRESH)
private Rol rol;
#ManyToOne(cascade = CascadeType.REFRESH)
private Perfil perfil;
#OneToOne (cascade = CascadeType.ALL)
private IntentosBloqueo intentos;
private boolean superUsuario;
private int borrado;
private int esManager;
#OneToMany ( cascade = {CascadeType.ALL} , fetch = FetchType.LAZY)
private Collection<UsuarioSociedad> sociedades;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
#JoinTable (name="USR_UND_VIS",
joinColumns={
#JoinColumn (name="ID_USU", table="USUARIO", referencedColumnName="ID"),
},
inverseJoinColumns=
#JoinColumn (name="ID_UNI", table="UND_ORG", referencedColumnName="ID")
)
private List<UnidadOrganizativa> unidadesVisibles;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
#JoinTable (name="USR_UND_DIS",
joinColumns={
#JoinColumn (name="ID_USU", table="USUARIO", referencedColumnName="ID"),
},
inverseJoinColumns=
#JoinColumn (name="ID_UNI", table="UND_ORG", referencedColumnName="ID")
)
private List<UnidadOrganizativa> unidadesDisponibles;
Because Named query works on Entity objetc not on datbase column. You try to find another entity object which contains that id. In That case your named query will give you the object of that entity class and from that object u can get the id or whtever fiels of that entity.
JPA named query is not like SQL or oracle query.
Iin in DB your column name is xyz but in entity your column name is ABC then you have to fetch ABC in named query not XYZ.