Hibernate #OneToMany where discriminatorValue = 'SOMETHING' - jpa

Table pdp_billable_field_state carries configuration for various fields.
Owner of configuration can be any number of Entity`s
This configuration is same for each entity that matches the #DiscriminatorValue
#Getter
#Setter
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "entity_type")
#Table(name = "pdp_billable_field_state")
public abstract class EntityFieldStateJpa extends AuditableJPA {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#ManyToOne
#JoinColumn(name = "status_id")
private StatusJpa status;
#Column(name = "field", columnDefinition= "varchar(255)")
private String field;
private boolean disabled;
private boolean hidden;
}
#DiscriminatorValue("PURCHASE")
public class PurchaseEntityFieldStateJpa extends EntityFieldStateJpa {}
#Getter
#Setter
#Entity
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "pdp_purchase")
public class PurchaseJpa {
// omitted
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
// i do not have a join_column since all records with entity_type PURCHASE map to all purchases, as these are configurations used by all purchases. Should i try and introduce #JoinTable maybe?
#Where(clause = "entity_type='PURCHASE'")
private List<PurchaseEntityFieldStateJpa> fieldStates;
}

Related

Joining three tables with #OneToMany association

I have three tables.
1.Street (street_id, settlement_entity_id, street_name),
2.Settlement_entity (settlement_entity_id, settlement_id, settlement_name), for example could be community, regional, municipality.. and
3.Settlement (settlement_id, settlement_name), for example could be city, town, township, village....
Relation - Street - Settlement_entity = > onetomany
Relation - Settlement_entity - Settlement = > onetomany
I want when I enter the name of the street, I get the settlement entity as above
as in parentheses and after that the settlement name with characteristics that are not to be the subject of this application, such as for example the house/apartment number, floor, longitude, latitude, altitude of the settlement.
entity
Street.java
package net.javaguides.springboot.entity;
#Entity
#Table(name = "street")
public class Street {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long street_id;
#Column(name = "street_name")
private String street_name;
public Street(String street_name) {
super();
this.street_name = street_name;
}
// getter and setters
entity
Settlement_entity.java
package net.javaguides.springboot.entity;
import javax.persistence.Column;
#Entity
#Table(name = "settlement_entity")
public class SettlementEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long settlement_entity_id;
#Column(name = "settlement_entity_name")
private String settlement_entity_name;
public SettlementEntity(String settlement_entity_name) {
super();
this.settlement_entity_name = settlement_entity_name;
}
// getters and setters
public void setSettlement_entity_name(String settlement_entity_name) {
this.settlement_entity_name = settlement_entity_name;
}
}
entity
Settlement.java
package net.javaguides.springboot.entity;
import javax.persistence.Column;
#Entity
#Table(name = "settlement")
public class Settlement {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long settlement_id;
#Column(name = "settlement_name")
private String settlement_name;
public Settlement(String settlement_name) {
super();
this.settlement_name = settlement_name;
}
// getters and setters
}
I creating according suggestion from -thelearner new linking entity which would be used for mapping that particular table.
entity linking table
StreetSettlementEntitySettlement.java
package net.javaguides.springboot.entity;
import javax.persistence.CascadeType;
public class StreetSettlementEntitySettlement {
#Id
#GeneratedValue
private long id;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "street_id")
private Street street;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "settlement_entity_id")
private SettlementEntity settlement_entity;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "settlement")
private Settlement settlement;
public StreetSettlementEntitySettlement(long id, Street street, SettlementEntity
settlement_entity, Settlement settlement) {
super();
this.id = id;
this.street = street;
this.settlement_entity = settlement_entity;
this.settlement = settlement;
}
}
Directory structure
I saw some proposal from thelearner like this:
It's not clear for me and don't understanding. Where should I put those three classes or should do something else. Repo's is clear.
Any help and explanation would be appreciated. Thank you

spring data JPA OneToMany query pagination of child (many) table

I have the following code. The number of rows in the One table will be about 100 and the number of rows in the Many table will be several hundred thousand (millions). I'm going to need to paginate the Many rows per single row in One when I query.
I'm not sure how to accomplish this.
My first thought is to get only the rows (and NOT the manyList content) in One but not even sure of that in JPA OneManyRepository. And then for each row use it's id primary key to query the Many with that one_id value and do pagination that way.
Any help will be apprecited.
Thanks,Jim
public interface OneManyRepository extends JpaRepository<One, Long> {
#Query(value = "select one.id,one.columnOne,one.columnTwo from one", nativeQuery = true)
Optional<List<One2>> findAllOne();
#Query(value = "select many.someTimeValue,many.value from many where many.one_id = :id", nativeQuery = true)
Optional<List<Many>> findAllBy(#Param("id") long id);
}
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class One2 {
private Long id;
private String columnOne;
private String columnTwo;
}
#Entity
#Table(name = "one")
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class One {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
private Long id;
private String columnOne;
private String columnTwo;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "one")
private List<Many> manyList;
}
#Entity
#Table(name = "many")
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class Many {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
private Long id;
#ManyToOne
private One one;
private long someTimeValue;
#Column(length = 10)
private String value;
}

Unable to delete entity using Spring Data Jpa

I have a bi-directional mapping between Customer, Order and LineItems. When trying to delete using deleteById method of Spring Data JPA, the entities are not getting deleted and I do not see any exception.
#Entity
#Table(name = "customers")
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Data
public class Customer implements UserDetails {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotEmpty(message = "customer name cannot be empty")
private String name;
#Column(unique = true)
#Email(message = "customer email address should be valid email address")
private String email;
#OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JsonManagedReference
private Set<Order> orders;
private String password;
#Data
#NoArgsConstructor
#Builder
#AllArgsConstructor
#EqualsAndHashCode(exclude = {"customer", "lineItems"})
#ToString(exclude = {"customer", "lineItems"})
#Entity
#Table(name = "orders")
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Min(value = 2000, message = "Min order value should be 2000 INR")
#Max(value = 10_000, message = "Max order value can be 10000 INR")
private double price;
#PastOrPresent(message = "Order date cannot be in future")
private LocalDate date;
#ManyToOne
#JoinColumn(name="customer_id", nullable = false)
#JsonBackReference
private Customer customer;
#OneToMany(mappedBy = "order",
cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
orphanRemoval = true
)
private Set<LineItem> lineItems;
//scaffolding code
// set the bidirectional mapping
public void addLineItem(LineItem lineItem){
if(this.lineItems == null){
this.lineItems = new HashSet<>();
}
this.lineItems.add(lineItem);
lineItem.setOrder(this);
}
}
#Data
#NoArgsConstructor
#EqualsAndHashCode(exclude = "order")
#ToString(exclude = "order")
#Builder
#AllArgsConstructor
#Entity
#Table(name="line_items")
public class LineItem {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private int qty;
private double price;
private String name;
#JsonIgnore
#ManyToOne
#JoinColumn(name="order_id", nullable = false)
private Order order;
}
this.orderRepository.deleteById(orderId);
Error:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.classpath.ordersapi.model.Customer.orders, could not initialize proxy - no Session\r\n\tat org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:612)\r\n\tat org.hibernate.collection.internal

JPA two Entities one Relationship: How do I obtain a Set of an entity that is linked through a relationship?

I have three tables each mapping to one of these entities. The 'assigned' table acts as the relationship between 'users' and 'roles' with a foreign key to each table. How would I map this on my entities so that I can get a Set of EntityRoles from the UserEntity? I can't quite figure out how to make this work. Is this even possible?
#Entity
#Table(name = "users")
public class UserEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="user_id")
private long id;
#Column(name="user_username")
private String username;
#Column(name="user_password")
private String password;
#Column(name="user_email")
private String email;
//I want to be able to get a set of RoleEntities
#OneToMany(fetch = FetchType.LAZY, mappedBy = "id")
private Set<RoleEntity> roles;
}
#Entity
#Table(name = "assigned")
public class AssignedEntity implements Serializable {
#Id
//#Column(name = "assigned_role")
#ManyToOne(targetEntity = RoleEntity.class, fetch = FetchType.LAZY)
#JoinColumn(name = "fk_role")
private long roleId;
#Id
//#Column(name = "assigned_user")
#ManyToOne(targetEntity = UserEntity.class, fetch = FetchType.LAZY)
#JoinColumn(name = "fk_user")
private long userId;
}
#Entity
#Table(name = "roles")
public class RoleEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="role_id")
#OneToOne(fetch = FetchType.LAZY, mappedBy="roleId")
private long id;
#Column(name="role_name")
private String name;
}
You are using an incorrect/inconvenient mapping. Always keep things as simply as possible.
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue
private Long id;
#ManyToMany(fetch = FetchType.LAZY)
private List<Role> roles;
}
#Entity
#Table(name = "roles")
public class Role {
#Id
private Long id;
#Column
private String name;
}
A persistent provider will create a (valid) join table for you. You can specify the name of the join table using #JoinTable annotation. Also you will need to think about auto generation values of id for the Role entity: the roles table is something like a reference data table. So, probably, you will need to hardcode the id values.
To get user roles (in the persistent context):
user.getRoles()

Spring data : issue with OneToOne relationship

I am developping a webapp (Spring J2EE/angularjs)
I want to set a relationship between two entities :
citizen (id, lastName, city)
city (id, cityName)
A citizen live in only one city.
I need to find a city from a citizen.
I don't need to find a citizen from a city.
I have done that :
#Entity
#Table(name = "citizen")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Citizen implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "last_name")
private String lastName;
#OneToOne
private City city;
}
#Entity
#Table(name = "city")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class City implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "city_name")
private String cityName;
}
In database I have inserted data. Citizen 1, 2 and 3 are linked to City 1
and Citizen 4 is linked to City 2
When I try to load all citizen, I am getting the error:
More than one row with the given identifier was found: 1, for class: com.myApp.rh.domain.Citizen
What's wrong in my entities?
Thanks
It seems that you are missing the #JoinColumn annotation in your Citizen entity.
#Entity
#Table(name = "citizen")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Citizen implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "last_name")
private String lastName;
#OneToOne
#JoinColumn(name = "id", unique = true)
private City city;
}
#Entity
#Table(name = "city")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class City implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "city_name")
private String cityName;
}