JPA query for 3 tables - sql

I want to create JPA query for configuring multiple Terminals to one Contract:
CREATE TABLE `contracts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
) ENGINE=InnoDB;
CREATE TABLE `contracts_terminals` (
`terminal_id` int(11) DEFAULT NULL,
`contract_id` int(11) DEFAULT NULL,
) ENGINE=InnoDB;
CREATE TABLE `terminals` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB;
How I can create JPA query which uses table contracts_terminals to assign multiple terminals to one contract?
I use latest MariaDB.
Entities:
Contracts:
#Entity
#Table(name = "contracts")
public class Contracts implements Serializable {
private static final long serialVersionUID = 3873648042962238717L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
#Column(length = 255)
private String name;
......
}
Terminals:
#Entity
#Table(name = "terminals")
public class Terminals implements Serializable {
private static final long serialVersionUID = 5288308199642977991L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, updatable = false, nullable = false, length = 3)
private int id;
#Column(length = 255)
private String name;
....
}
ContractTerminals:
#Entity
#Table(name = "contract_terminals")
public class ContractTerminals implements Serializable {
private static final long serialVersionUID = 1191148141983861602L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
#Column(length = 4)
private Integer terminal_id;
#Column(length = 4)
private Integer contract_id;
....
}

Related

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 unidirectional one-to-one mapping

I have the following table structure.
(The unique constraint is to avoid multiple 'details' to the same employee - I can't change the db structure).
https://i.ibb.co/r3pYQFj/fk.png
create table employee (
employee_id number(19),
salary number(10),
constraint pk_employee primary key (employee_id)
);
create table employee_details (
employee_details_id number(19),
employee_id number(19) not null,
address varchar2(256),
gender char(1),
constraint fk_employee foreign key (employee_id) references employee (employee_id),
constraint fk_employee_unq unique (employee_id)
);
Model class:
#Entity
#Table(name = "EMPLOYEE")
public class Employee implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "empgen")
#SequenceGenerator(name = "empgen", sequenceName = "SEQ_EMP", allocationSize = 1)
#Column(name = "EMPLOYEE_ID")
private Long id;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name="EMPLOYEE_ID")
private EmployeeDetail empDetail;
...
#Entity
#Table(name = "EMPLOYEE_DETAIL")
public class EmployeeDetail implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "empdetgen")
#SequenceGenerator(name = "empdetgen", sequenceName = "SEQ_EMP_DET", allocationSize = 1)
#Column(name = "EMPLOYEE_DETAILS_ID")
private Long id;
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
...
I have a rest controller that receive a JSON like this:
{
"employee": {
"salary": 80000,
"empDetail": {
"adress": "ST EXAMPLE",
"gender": "M"
}
}
}
I'm trying to persist all the entities via hibernate (5.4.28) saving Employee as the first entity, then with its primary key, EmployeeDetails using it's parent primary key but I get this:
java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("DCC"."EMPLOYEE_DETAILS"."EMPLOYEE_ID")
Why it's trying to save the child before the parent?
How the the class should be mapped?
I guess it's because Hibernate thinks that by putting #JoinColumn on Employee.empDetail, EMPLOYEE_ID belongs to the employee_details table.
Try putting creating a property EmployeeDetail.employee and put #JoinColumn on that one. If you need a reference from Employee, use #OneToOne(mappedBy=...).
How to use #JoinColumn
Activate logging to see which statements are executed

How to fix 'ERROR SqlExceptionHelper Column 'cardinalidadid' not found' error in jpa

I want to map an entity, which has a relationship with another table, but when mapping that relationship, it doesn't find the "Cardinality" column.
This is the code:
Entity elemento:
#Entity
#Table(name = "elemento")
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="clave", discriminatorType = DiscriminatorType.STRING, length=10)
public class Elemento implements Serializable, GenericInterface {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "clave", insertable = false)
private String clave;
#Column(name = "numero")
private String numero;
#Column(name = "nombre")
private String nombre;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "Proyectoid")
private Proyecto proyecto;
#Column(name = "descripcion")
private String descripcion;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "EstadoElementoid", referencedColumnName="id")
private EstadoElemento estadoElemento;
Entity actor:
#Entity
#Table(name = "actor")
#Inheritance(strategy=InheritanceType.JOINED)
#PrimaryKeyJoinColumn(name = "Elementoid", referencedColumnName = "id")
#DiscriminatorValue("ACT")
public class Actor extends Elemento implements Serializable, GenericInterface, ElementoInterface {
private static final long serialVersionUID = 1L;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "Cardinalidadid", referencedColumnName = "id")
private Cardinalidad cardinalidad;
This is the description of the tables:
TABLE ACTOR:
| actor | CREATE TABLE `actor` (
`otraCardinalidad` varchar(45) DEFAULT NULL,
`Elementoid` int(11) NOT NULL,
`Cardinalidadid` int(11) NOT NULL,
PRIMARY KEY (`Elementoid`),
KEY `FKActor872913` (`Cardinalidadid`),
KEY `FKActor148309` (`Elementoid`),
CONSTRAINT `FKActor148309` FOREIGN KEY (`Elementoid`) REFERENCES
`elemento` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FKActor872913` FOREIGN KEY (`Cardinalidadid`) REFERENCES
`cardinalidad` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
TABLE CARDINALIDAD
| cardinalidad | CREATE TABLE `cardinalidad` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nombre` varchar(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniqueCardinalidad` (`nombre`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 |
This error appears
02:57:43.663 [qtp1469821799-35] DEBUG
com.mchange.v2.c3p0.impl.NewPooledConnection -
com.mchange.v2.c3p0.impl.NewPooledConnection#48c2c8ce handling a
throwable. java.sql.SQLException: Column 'cardinalidadid' not found.

JPA - I get multiple rows instead of 1

I spent many hours to solve my problem but without success. I'd like to achieve something like this (but with ONE row instead of TWO):
My database:
CREATE TABLE odo.d_kryterium_naruszen (
id bigserial primary key,
kryterium text not null,
data_wpr TIMESTAMP not null DEFAULT clock_timestamp(),
opr bigint not null
);
CREATE TABLE odo.d_czynnik_naruszen (
id bigserial primary key,
czynnik text not null,
id_kryterium_naruszen bigint not null references odo.d_kryterium_naruszen(id),
stopien NUMERIC(10,2) not null,
data_wpr TIMESTAMP not null DEFAULT clock_timestamp(),
opr bigint not null
);
CREATE TABLE odo.d_dotkliwosc_naruszenia (
id bigserial primary key,
zakres numrange not null,
ocena text not null,
opis text not null,
wymagane_dzialanie text not null,
data_wpr TIMESTAMP not null DEFAULT clock_timestamp(),
opr bigint not null
);
CREATE TABLE odo.ocena_naruszenia_wynik (
id bigserial primary key,
wartosc_dotkliwosci_naruszenia NUMERIC(10,2) not null,
status_id bigint not null references odo.d_status_oceny_naruszenia(id),
ocena_naruszenia_id bigint not null references odo.ocena_naruszenia(id),
data_wpr TIMESTAMP not null DEFAULT clock_timestamp(),
opr bigint not null
);
create table odo.czynnik_naruszen_wynik(
id bigserial primary key,
ocena_naruszenia_wynik_id bigint not null references odo.ocena_naruszenia_wynik(id),
czynnik_naruszen_id bigint not null references odo.d_czynnik_naruszen(id),
komentarz text,
czynnik_wybrany boolean not null default false
wartosc_wybrana NUMERIC(10,2) not null,
data_wpr TIMESTAMP not null DEFAULT clock_timestamp(),
opr bigint not null
);
And here my entities:
#Data
#Entity
#Table(schema = "odo", name = "d_kryterium_naruszen")
public class ViolationCriterion extends BaseEntity {
#Column(name = "kryterium")
private String criterion;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "id_kryterium_naruszen")
private List<ViolationFactor> violationFactors;
}
#Data
#Entity
#Table(schema = "odo", name = "d_czynnik_naruszen")
public class ViolationFactor extends BaseEntity {
#Column(name = "czynnik")
private String factor;
#Column(name = "stopien")
private float degree;
#OneToMany
#JoinColumn(name = "czynnik_naruszen_id")
private List<IncidentAssessmentFactor> incidentAssessmentFactor;
}
#Data
#Entity
#Table(schema = "odo", name = "czynnik_naruszen_wynik")
public class IncidentAssessmentFactor extends BaseEntity {
#Column(name="komentarz")
private String comment;
#Column(name="czynnik_wybrany")
private Boolean factorIsSelected;
#Column(name = "wartosc_wybrana")
private Float value;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name="ocena_naruszenia_wynik_id", updatable=false, insertable=false)
private IncidentAssessment incidentAssessment;
}
#Data
#Entity
#Table(schema = "odo", name = "ocena_naruszenia_wynik")
public class IncidentAssessment extends BaseEntity {
#Column(name="ocena_naruszenia_id")
private Long incidentAssessmentId;
#Column(name = "wartosc_dotkliwosci_naruszenia")
private Float severityDegreeValue;
My repository:
#Repository
public interface ViolationCriterionRepository extends JpaRepository<ViolationCriterion, Long> {
// #Query("select vc from ViolationCriterion vc inner join vc.violationFactors vf inner join vf.incidentAssessmentFactor iaf inner join iaf.incidentAssessment ia where ia.incidentAssessmentId = ?1 group by vc ")
#Query("select vc from ViolationCriterion vc inner join vc.violationFactors vf inner join vf.incidentAssessmentFactor iaf inner join iaf.incidentAssessment ia where ia.incidentAssessmentId = ?1 group by vc ")
// #Query(value = "select kn.kryterium from odo.d_kryterium_naruszen kn join odo.d_czynnik_naruszen cn on kn.id = cn.id_kryterium_naruszen join odo.czynnik_naruszen_wynik cnw on cnw.czynnik_naruszen_id = cn.id join odo.ocena_naruszenia_wynik onw on cnw.ocena_naruszenia_wynik_id = onw.id where onw.ocena_naruszenia_id = ?1 group by kn.id, cn.id, cnw.id, onw.id", nativeQuery = true)
// #Query(value = "select kn.id, kn.kryterium, kn.data_wpr, kn.opr, cn.id, cn.czynnik, cn.stopien, cn.opr, cn.data_wpr, cnw.id, cnw.data_wpr, cnw.opr, cnw.komentarz, cnw.czynnik_wybrany, cnw.wartosc_wybrana, onw.id, onw.data_wpr, onw.opr, onw.ocena_naruszenia_id, onw.wartosc_dotkliwosci_naruszenia from odo.d_kryterium_naruszen kn join odo.d_czynnik_naruszen cn on kn.id = cn.id_kryterium_naruszen join odo.czynnik_naruszen_wynik cnw on cnw.czynnik_naruszen_id = cn.id join odo.ocena_naruszenia_wynik onw on cnw.ocena_naruszenia_wynik_id = onw.id where onw.ocena_naruszenia_id = ?1 group by kn.id, cn.id, cnw.id, onw.id", nativeQuery = true)
List<ViolationCriterion> findIncidentAssessmentByIncidentAssessmentId(Long incidentId);
// List<ViolationCriterion> findByViolationFactorsIncidentAssessmentFactorIncidentAssessmentIncidentAssessmentIdGroupByViolationCriterionCriterion(Long id);
}
And here I call my repository:
List<ViolationCriterion> violationCriteria = violationCriterionRepository.findIncidentAssessmentByIncidentAssessmentId(id);//vi
In a table czynnik_naruszen_wynik I have 2 different rows because I have 2 rows in table ocena_naruszenia_wynik. The problem is that I have multiple values of entity IncidentAssessmentFactor instead of 1

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.