how to set #SequenceGenerator schema in multitenancy - jpa

I'm facing this issue, my entity Profile is :
#Entity
#Table(name="profile")
#Multitenant(value=MultitenantType.TABLE_PER_TENANT)
#TenantTableDiscriminator(type=TenantTableDiscriminatorType.SCHEMA, contextProperty="eclipselink.tenant-id")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 17)
public class Profile implements Serializable, Comparable<Profile> {
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "profile_id_generator", sequenceName = "profile_identification_seq", allocationSize = 1, schema = ?)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "profile_id_generator")
#Column(unique = true, nullable = false)
#Expose
private Integer identification;
Please, how can i set the schema in the #SequenceGenerator annotation according to the current user tenant-id

Related

How to delete entities in a chained one-to-many and many-to-many JPA relationship

I have a chain of entities as follows:
#Entity
#Table(name = "Patients")
public class Patient extends TimeStampedPersistable{
private static final long serialVersionUID = 1L;
#OneToMany(mappedBy="patient", cascade = CascadeType.ALL)
#PrivateOwned
private List<Insurance> insurances;
}
#Entity
#Table(name = "insurance")
public class Insurance extends PersistableEntity {
private static final long serialVersionUID = 1L;
#ManyToOne(optional=false)
#JoinColumn(name="patient_id", nullable=false)
private Patient patient;
#Column(name = "policy_number", unique = false, nullable = true)
private String policyNumber;
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
#JoinTable(name = "insurance_companycodes", joinColumns = {
#JoinColumn(name = "insurance_id", referencedColumnName = "id", nullable = false, updatable = false) }, inverseJoinColumns = {
#JoinColumn(name = "insuranceCompanyCode_id", referencedColumnName = "id", nullable = false, updatable = false) })
private Set<InsuranceCompanyCode> insuranceCompanyCodes = new HashSet<>();
}
#Entity
#Table(name = "insurance_company_codes")
public class InsuranceCompanyCode extends PersistableEntity {
private static final long serialVersionUID = 1L;
#Column(name = "identifier", unique = true, nullable = true)
private String identifier;
#ManyToMany(mappedBy = "insuranceCompanyCodes", fetch = FetchType.LAZY)
private Set<Insurance> insurances = new HashSet<>();
}
I need to remove insurance items from the Patient object. I am using the following code:
for (Iterator<Insurance> iterator = patient.getInsurances().iterator(); iterator.hasNext();) {
iterator.next();
iterator.remove();
}
This seems to work for child entities that don't have child entities, however in this situation the Insurance entity has child entities and is not actually removed (no exceptions are displayed). Note, I am using the EclipseLink specific annotation #PrivateOwned which I expected would have forced the removal of the Insurance entities.
Any guidance, suggestions appreciated!

JPA cascade - deletion is not working when id is different in join table

I am using spring JPA to insert and delete the records in these tables. I can able to insert the record, but deletion is not happening due to different id's in emp_workstation table. If both employee_id and workstation_id were same then delete is working fine, but if both the id's were not same then delete not happening in employee table and emp_workstation table (cascade has set to 'ALL'). Does anybody face this problem before or know how to solve this issue?
Employee.java
#Setter
#Getter
#Builder(toBuilder = true)
#AllArgsConstructor(access = AccessLevel.PUBLIC)
#NoArgsConstructor(access = AccessLevel.PUBLIC)
#Entity
#Table(name = "employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sq_employee_id")
#SequenceGenerator(name = "sq_employee_id", sequenceName = "sq_employee_id", allocationSize = 1)
private Long id;
#Column(name = "employee_name", length = 50)
private String name;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "emp_workstation", joinColumns = {
#JoinColumn(name = "employee_id") }, inverseJoinColumns = { #JoinColumn(name = "workstation_id") })
private Workstation workstation;
}
Workstation.java
#Setter
#Getter
#Builder(toBuilder = true)
#AllArgsConstructor(access = AccessLevel.PUBLIC)
#NoArgsConstructor(access = AccessLevel.PUBLIC)
#Entity
#Table(name = "workstation")
public class Workstation {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sq_workstation_id")
#SequenceGenerator(name = "sq_workstation_id", sequenceName = "sq_workstation_id", allocationSize = 1)
private Long id;
#Column(name = "workstation_name", nullable = false, length = 100)
private String name;
#Column(name = "workstation_area", nullable = false, length = 100)
private String name;
#OneToOne(mappedBy = "workStation")
private Employee employee;
}
Example: In EMP_WORKSTATION table, if EMPLOYEE_ID and WORKSTATION_ID were same then deletion is working fine. but if both id were different then deletion is not working.
Thanks

Revision contains null values of other fields if change the #oneToMany - entity by adding a new entity

When a new address is added for a person, a new revision should be created. A revision is created, but the remaining fields of the entity in the revision are marked null.
Different and correct:
When I change a name for a person, a revision is created where all fields are entered.
Person Entity:
#Entity
#Table(name = "Person")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Audited
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#OneToMany(mappedBy="person")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
Person Audit Entity:
#Entity
#Table(name = "person_aud")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class PersonAud implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private AuditIdentity auditIdentity;
#Column(name = "revtype")
private Short revtype;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#ManyToOne
#MapsId("auditIdentity.id")
#JoinColumn(name = "id", nullable = false)
private Person person;
#OneToMany
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
Address Entity:
#Entity
#Table(name = "address")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Audited
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
private Long id;
#Column(name = "street")
private String street;
#Column(name = "house_number")
private String houseNumber;
#Column(name = "zip_code")
private String zipCode;
#Column(name = "city")
private String city;
#Column(name = "state_province")
private String stateProvince;
#Column(name = "country")
private String country;
#ManyToOne
#JsonIgnoreProperties("addresses")
private Person person;
#OneToOne
#JsonIgnoreProperties("addresses")
#NotAudited
private PersonAud personAud;
If I add a new address that belongs to person XY, then my table looks like this:
PERSON_AUD:
ID: 1
REV: 1001
REVTYPE: 1
FIRST_NAME: NULL
LAST_NAME: NULL
For example, if I change the first name, the fields for the first_name and last_name are entered.
Problem solved (not perfect):
I changed the line:
#OneToMany(mappedBy="person")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
to:
#OneToMany(cascade = {CascadeType.ALL})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
Now the process works like:
Add a new person with empty Address array
Add a new Address which refers to the person id
Action like a PUT on this Person assigning the address-object.
= PERSON_AUD table will contain the revision and the fields.
PROBLEM:
it is not perfect because you have to assign the address manually to the person.
Is there any other possible solution?

Criteria JPA - Specific attribute

I need to create a criteria query that represents the follow JPQL:
I tryed to specify the class RegraContrato but no success.
SELECT G FROM Grupo G JOIN G.regras R WHERE TYPE(R) = RegraContrato AND R.numeroContrato in(123)
#Entity
#Table(name = "GRUPO_ACESSO")
public class Grupo {
#OneToMany(mappedBy = "grupo",cascade = CascadeType.ALL,fetch = FetchType.EAGER,orphanRemoval = true)
private Set<Regra> regras = Sets.newHashSet();
}
#Entity
#Table(name = "REGRA_ACESSO")
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Regra {
private static final long serialVersionUID = 5994730323053219858L;
#Id
#SequenceGenerator(name = "REGRA_ID_GENERATOR",sequenceName = "REGRA_SEQUENCE",allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "REGRA_ID_GENERATOR")
#Column(name = "ID")
private Long id;
}
#Entity
#PrimaryKeyJoinColumn(name = "ID")
#Table(name = "REGRA_CNPJ")
public class RegraCNPJ extends Regra {
#Column(name = "CNPJ")
private String cnpj;
}
#Entity
#PrimaryKeyJoinColumn(name = "ID")
#Table(name = "REGRA_CONTRATO")
public class RegraContrato extends Regra {
private static final long serialVersionUID = -2840125767126128182L;
#Column(name = "NUMERO_CONTRATO")
private Long numeroContrato;
}

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property customer invoice

I am new to spring based project,
I have the requirement to create the entity relationship mapping between orders and invoices with OneToMany, and tried below mappings, but ending up with mapping error,
Could you please point me out to fix this issue.
#Entity
#Table(name="Customers")
public class Customers implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "CustomerId", nullable = false)
private Long CustomerId;
#OneToMany(cascade=CascadeType.ALL, mappedBy="Customers")
private Set<Orders> Orders = new HashSet<Orders>();
}
#Entity
#Table(name="Orders")
public class Orders implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "orderId", nullable = false)
private Long orderId;
#JoinColumn(name="CustomerId")
#ManyToOne
private Customers customers;
#OneToOne (optional=false,cascade=CascadeType.ALL, mappedBy="orders",targetEntity=Invoices.class)
private Invoices invoices;
}
#Entity
#Table(name="Invoices")
public class Invoices implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "invoiceId", nullable = false)
private Long invoiceId;
#OneToOne(optional=false,cascade=CascadeType.ALL, mappedBy="invoices",targetEntity=Orders.class)
private Orders orders;
}
Error message:
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.mycompany.myproject.persist.entity.Orders.Customers in com.mycompany.myproject.persist.entity.Customers.Orders
Probably because Orders has a property 'customers' and not 'Customers' (as specified by the 'mappedBy' attribute).
You should tidy up your class names and fields as below:
#Entity
#Table(name="Customers")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "CustomerId", nullable = false)
private Long customerId;
#OneToMany(cascade=CascadeType.ALL, mappedBy="customer")
private Set<Order> orders = new HashSet<Order>();
}
#Entity
#Table(name="Orders")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "orderId", nullable = false)
private Long orderId;
#ManyToOne
#JoinColumn(name="CustomerId")
private Customer customer;
#OneToOne(optional=false, cascade=CascadeType.ALL, mappedBy="order")
private Invoice invoice;
}
#Entity
#Table(name="Invoices")
public class Invoice implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "invoiceId", nullable = false)
private Long invoiceId;
#OneToOne(optional=false,cascade=CascadeType.ALL)
#JoinColumn(name = "InvoiceId")
private Order order;
}