Hibernate Enver - Listening for only one change in referenced class - spring-boot

I have an entity as shown below that I am auditing using Hibernate Enver
#Entity
#Table(name = "watch_item")
#Audited
public class WatchItemEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Type(type = "uuid-char")
#Column(name = "watch_item_id", columnDefinition = "VARCHAR(36)")
private UUID watchItemId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "watch_model_id")
private WatchModelEntity watchModel;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "private_user_id")
private PrivateUserEntity privateUser;
private String serialNumber;
private Integer productionYear;
private String generalCondition;
private Boolean isMovementFullyFunctional;
private Boolean isInOriginalCondition;
private String comment;
private Boolean isProofOfPurchaseAvailable;
private String country;
private Boolean isCustomsDeclared;
private Boolean hasPaper;
private Boolean hasBox;
private String otherAccessories;
#CreatedDate private LocalDateTime createdDate;
#LastModifiedDate private LocalDateTime modifiedDate;
private String lastServiceProvider;
private LocalDate lastServiceDate;
private BigDecimal lastServiceCost;
private BigDecimal purchasedPrice;
private LocalDate purchasedOn;
...
}
As you can see, it has a PrivateUserEntity field. I want Hibernate Envers to record a change when the privateUser changes (and not record changes in PrivateUserEntity that correspond to the privateUser). However, I don't want to create a Private_User_Aud table. To give some context, a WatchItem can only be owned by one PrivateUser and hence, when the PrivateUser field changes, that means that the WatchItem's owner changed. The entity can be seen below
#Entity
#Table(name = "private_user")
public class PrivateUserEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Type(type = "uuid-char")
#Column(name = "private_user_id", columnDefinition = "VARCHAR(36)")
private UUID privateUserId;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
private UserEntity user;
#LastModifiedDate private LocalDate modifiedDate;
private String title;
private String firstName;
private String lastName;
private String phone;
private LocalDate dateOfBirth;
private String email;
private String gender;
private String nationality;
private String residencyPermitType;
private LocalDate residencyPermitValidSince;
private String preferredLanguage;
...
}
Is this possible? And if so, how?

You can disable audit for it, doesn't work?
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "private_user_id")
#NotAudited
private PrivateUserEntity privateUser;

Related

Need to save/update child 500 or more rows in parent-child relationship with-in 10sec using Spring-Data-JPA

I have a scenario where I need to save or update 500 or more item in postgres db within 10sec using spring-data-jpa. below are my domain and service class.
GroupingForm.java
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#Entity
#Table(name = "GroupingForm")
public class GroupingForm implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name = "grouping_form_id",unique = true, nullable = false)
private UUID groupingFormId;
#Column(name = "grouping_form_name")
private String groupingFormName;
#Column(name = "vid")
private String vid;
#Column(name = "vendor_name")
private String vendorName;
#Column(name = "hovbu")
private String hovbu;
#Column(name = "fid")
private String fid;
#Column(name = "factory_name")
private String factoryName;
#Column(name = "item_count")
private Integer itemCount;
#CreationTimestamp
#Column(name = "creation_date")
private Timestamp creationDate;
#Column(name = "created_by")
private String createdBy;
#UpdateTimestamp
#Column(name = "modified_date")
private Timestamp modifiedDate;
#Column(name = "modified_by")
private String modifiedBy;
#Column(name = "product_engineer")
private String productEngineer;
#Column(name = "status")
private String status;
#Column(name = "sourcing_type")
private String sourcingType;
#Column(name = "total_comments")
private Integer totalComments;
#Column(name = "factory_name_chinese")
private String factoryNameChinese;
#Column(name = "grouping_form_type")
private String groupingFormType;//to save as Product/transit/Product_transit
#Column(name = "ref_id")
private String refId;
#JsonManagedReference
#OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ProductItemsMapping> productItems = new ArrayList<>();
#JsonManagedReference
#OneToMany(mappedBy = "groupingForm", cascade = CascadeType.ALL, orphanRemoval = true)
private List<TransitItemsMapping> transitItems = new ArrayList<>();
#Column(name = "pdf_status")
private String pdfStatus;
}
ProductItemsMapping.java
#Data
#Entity
#Table(name = "ProductItemsMapping")
public class ProductItemsMapping implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name = "product_item_id",unique = true, nullable = false)
private UUID productItemId;
#ToString.Exclude
#JsonBackReference
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "grouping_form_id")
private GroupingForm groupingForm;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(referencedColumnName = "dim_Item_ID",name = "item_id")
private Item item;
#Column(name ="item_relationship_id", insertable = false,updatable = false)
private String itemRelationshipId;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "item_relationship_id",referencedColumnName = "dim_item_relationship_id")
private VendorFactoryItem vendorFactoryItem;
#Column(name = "edam_id")
private String edamId;
#Column(name = "model_number")
private String modelNumber;
#Column(name = "description")
private String description;
#Column(name = "material")
private String material;
#Column(name = "finishing_colour")
private String finishingColour;
#Column(name = "dimensions")
private String dimensions;
#Column(name = "product_net_weight")
private String productNetWeight;
#Column(name = "insertion_order")
private Integer insertionOrder;
#Column(name = "comments")
private String comments;
#Column(name = "item_unique_id")
private String itemUniqueId;
}
TransitItemsMapping.java
#Data
#Entity
#Table(name = "TransitItemsMapping")
public class TransitItemsMapping implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name = "transit_Item_id",unique = true, nullable = false)
private UUID transitItemId;
#ToString.Exclude
#JsonBackReference
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "grouping_form_id")
private GroupingForm groupingForm;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(referencedColumnName = "dim_Item_ID",name = "item_id")
private Item item;
#Column(name ="item_relationship_id", insertable = false,updatable = false)
private String itemRelationshipId;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "item_relationship_id",referencedColumnName = "dim_item_relationship_id")
private VendorFactoryItem vendorFactoryItem;
#Column(name = "edam_id")
private String edamId;
#Column(name = "model_number")
private String modelNumber;
#Column(name = "description")
private String description;
#Column(name = "packaging_details")
private String packagingDetails;
#Column(name = "packaging_method")
private String packagingMethod;
#Column(name = "is_side_stack")
private String isSideStack;
#Column(name = "quantity")
private Integer quantity;
#Column(name = "dimensions")
private String dimensions;
#Column(name = "product_net_weight")
private String productNetWeight;
#Column(name = "plastic_bag_ind")
private String plasticBagInd;
#Column(name = "insertion_order")
private Integer insertionOrder;
#Column(name = "comments")
private String comments;
#Column(name = "item_unique_id")
private String itemUniqueId;
#Column(name = "itm_pak_qty")
private Integer itemPackQuantity;
}
Item.java
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#Entity
#Table(name = "Item")
public class Item implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
//#GenericGenerator(name = "uuid", strategy = "uuid2")
//#GeneratedValue(generator = "uuid")
#JsonIgnore
#Column(name = "dim_Item_ID", unique = true, nullable = false)
private UUID dimItemId;
//mdm columns start
#Valid
#EmbeddedId
private ItemId itemId;
#Column(name = "model")
private String model;
#Column(name = "description")
private String description;
#CreationTimestamp
#Column(name="effective_date")
private Timestamp effectiveDate;
#JsonIgnore
#Column(name="expiration_date")
private Timestamp expirationDate;
#JsonIgnore
#Column(name="business_area_number")
private Integer businessAreaNumber;
#JsonIgnore
#Column(name="business_area_desc")
private String businessAreaDesc;
#JsonIgnore
#Column(name="division_number")
private Integer divisionNumber;
#JsonIgnore
#Column(name="division_desc")
private String divisionDesc;
#JsonIgnore
#Column(name="sub_division_number")
private Integer subDivisionNumber;
#JsonIgnore
#Column(name="sub_division_desc")
private String subDivisionDesc;
#JsonIgnore
#Column(name="product_group_number")
private Integer productGroupNumber;
#JsonIgnore
#Column(name="product_group_desc")
private String productGroupDesc;
#JsonIgnore
#Column(name="assortment")
private Integer assortment;
#JsonIgnore
#Column(name="assortment_desc")
private String assortmentDesc;
#JsonIgnore
#Column(name="status")
private Integer status;
#JsonIgnore
#Column(name="status_desc")
private String statusDesc;
#Column(name = "origin_country")
private String originCountry;
#Column(name = "destination_country")
private String destinationCountry;
#Column(name = "is_private_brand")
private String isPrivateBrand;
#Column(name = "brand")
private String brandName;
#Column(name = "item_weight")
private Double itemWeight;
#Column(name = "in_box_height")
private Double inBoxHeight;
#Column(name = "in_box_width")
private Double inBoxWidth;
#Column(name = "in_box_depth")
private Double inBoxDepth;
#Column(name = "primary_image")
private String primaryImage;
#Column(name = "component_materials")
private String componentMaterials;
#Column(name = "product_detail")
private String productDetail;
#Column(name = "finishing_color")
private String finishingColor;
#Column(name = "packaging_method")
private String packagingMethod;
#Column(name = "packaging_quantity")
private Integer packagingQuantity;
#Column(name = "out_box_depth")
private Double outBoxDepth;
#Column(name = "out_box_height")
private Double outBoxHeight;
#Column(name = "out_box_width")
private Double outBoxWidth;
#Column(name = "net_weight")
private Double netWeight;
#Column(name = "plastic_bag_ind")
private String plasticBagInd;
//mdm columns ends
//Adhoc specific start
#JsonIgnore
#Column(name="is_current")
private Integer isCurrent;
#JsonIgnore
#Column(name="remark")
private String remark;
#JsonIgnore
#Column(name="is_valid")
private String isValid;
#CreationTimestamp
#Column(name="creation_date")
private Timestamp creationDate;
#JsonIgnore
#Column(name="created_by")
private String createdBy;
#JsonIgnore
#UpdateTimestamp
#Column(name="last_modified_date")
private Timestamp lastModifiedDate;
#Column(name = "is_adhoc_item")
private String isAdhocItem;
//Adhoc specific ends
#JsonIgnore
#OneToMany(cascade = CascadeType.ALL, mappedBy = "item")
private List<VendorFactoryItem> vendorFactoryItems;
#JsonIgnore
#OneToMany(cascade = CascadeType.ALL, mappedBy = "item")
private List<ProductItemsMapping> productItems = new ArrayList<>();
#JsonIgnore
#OneToMany(cascade = CascadeType.ALL, mappedBy = "item")
private List<TransitItemsMapping> transitItems = new ArrayList<>();
#Transient
#JsonIgnore
private Integer itemNumber;
#Transient
#JsonIgnore
private String itemRelationshipId;
#Transient
#JsonIgnore
private String vendorId;
#Transient
#JsonIgnore
private String retailer;
#Transient
#JsonIgnore
private String fid;
#Transient
#JsonIgnore
private String hovbu;
#Column(name="sourcing_type")
private String sourcingType;
#Column(name = "itm_pak_qty")
private Integer itemPackQuantity;
#Column(name = "barcode")
private String barcode;
#Column(name = "item_type")
private String itemType;
#Column(name = "item_cube")
private String itemCube;
}
VendorFactoryItem.java
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#Entity
#Builder
#Table(name = "vendorfactoryitem")
public class VendorFactoryItem implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#EmbeddedId
private VendorFactoryItemId vendorFactoryItemId;
#JsonIgnore
#Column(name = "dim_item_relationship_id")
private String itemRelationshipId;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumns({
#JoinColumn(name = "hovbu",updatable = false,insertable = false),
#JoinColumn(name = "item_number",updatable = false,insertable = false),
#JoinColumn(name = "retailer",updatable = false,insertable = false)
})
private Item item;
#Column(name = "item_id")
private String itemIdRel;
#Column(name = "is_adhoc_rel")
private String isAdHocRel;
#Column(name = "dim_factory_import_id")
private String dimFactoryImportId;
#Column(name = "factory_short_name")
private String factoryShortName;
#Column(name = "company_id")
private String companyId;
#Column(name = "vendor_short_name")
private String vendorShortName;
#Column(name = "remark")
private String remark;
#Column(name = "is_valid")
private String isValid;
#Column(name = "created_on")
private Timestamp createdOn;
#Column(name = "created_by")
private String createdBy;
#Column(name = "last_modified_date")
private Timestamp lastModifiedDate;
#Column(name = "effective_date")
private Timestamp effectiveDate;
#JsonIgnore
#OneToMany(cascade = CascadeType.ALL, mappedBy = "vendorFactoryItem")
private List<ProductItemsMapping> productItems = new ArrayList<>();
#JsonIgnore
#OneToMany(cascade = CascadeType.ALL, mappedBy = "vendorFactoryItem")
private List<TransitItemsMapping> transitItems = new ArrayList<>();
}
GroupingFormRepository.java
#Repository
public interface GroupingFormRepository
extends JpaRepository<GroupingForm, UUID>, GroupingFormRepositoryCustom {
}
GroupingFormService.java
#Transactional
public GroupingFormDto saveGroupingFormV1(GroupingFormDto groupingFormDto) {
//do the mapping DTO to DOMAIN..remove the code ..
**GroupingForm groupingFormSaved = groupingFormRepository.save(groupingForm);**
}
With in the GroupingForm object I am setting the transitItem and productItem to save or update. And also adding Item and VendorfactoryItems not for save or update. what are the best way I can optimize this save and update with in 10 sec while I am passing more than 500 productItem and 500 transitItem.
Thanks in advance.

How to get data from another table

#Entity
#Table(name="driver_duties")
public class Duties{
private String driverId;
private String hubName;
private String vehicleNumber;
// with getter and setters
}
another table
#Entity
#Table(name="driver_info")
public class Info{
private String driverId;
private String firstName;
private String lastName;
// with getter and setters
}
I want to get firstName and lastName in table driver_duties on the basis of driverId how can I get this. I am new to JPA I have tried #OnetoOne but not able to implement.
Add Duties as a data memeber in the class info
#Entity
#Table(name="driver_info")
public class Info{
private String driverId;
private String firstName;
private String lastName;
private Duties duties;
// with getter and setters
}
Ideally you need the following config, you should use an id attribute for every entity,
#Entity
#Table(name="driver_duties")
public class Duties{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private String id;
#Column(name = "hubName")
private String hubName;
#Column(name = "vehicleNumber")
private String vehicleNumber;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "duty_id")
private Info info;
// with getter and setters
}
#Entity
#Table(name="driver_info")
public class Info{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private String id;
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#OneToOne(mappedBy = "info", cascade = CascadeType.ALL,
fetch = FetchType.LAZY)
private Duties duties;
// with getter and setters
}

springboot jpa combine two tables

I want to query data from two tables,
location field in Translation is a foreign key from id field of Location
#Entity
#Table(name = "Translation")
#Data
public class Translation {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotNull private String language;
#NotNull private String name;
#NotNull private String description;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "location", nullable = false, insertable = false, updatable = false)
#Fetch(FetchMode.JOIN)
private Location location;
}
#Entity
#Table(name = "Location")
#Data
public class Location {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotNull private String code;
#NotNull private String type;
private Double longitude;
private Double latitude;
#Column(name = "parent_id")
private Integer parentId;
#OneToMany(targetEntity = Translation.class, mappedBy="id", fetch = FetchType.EAGER)
private Set<Translation> translations;
}
————————————————————————————————————————
But when I use a query
#Query(
"SELECT new com.afkl.travel.exercise.model.RetrieveLocationResponse("
+ "loc.code, tran.name, loc.type, loc.latitude, loc.longitude, tran.description, loc.parentId)"
+ "FROM Location loc LEFT JOIN loc.translation tran")
List<RetrieveLocationResponse> fetchLeftJoin();
All the fields related to Translation is null, having no idea what happened
UPDATE
The following ones work for me.
#OneToMany(mappedBy = "location", cascade = CascadeType.ALL)
#JsonIgnore
private Set<Translation> translations;
#ManyToOne
#JoinColumn(name = "location")
private Location location;
try
#OneToMany(mappedBy = "location", cascade = CascadeType.ALL)
#JsonIgnore
private Set<Translation> translations;
#ManyToOne
#JoinColumn(name = "location")
private Location location;

Spring JPA: How to insert data to join many tables with #ManytoMany relationship

I'm starting to learn Spring Java Framework . I created some Enity to join 2 Model like my Database. And now I want to insert to Join Table by JpaRepository. What i have to do?
This is my Code (Please fix help me me if something is not right)
Model Users_RoomId to define Composite Primary Key
#Embeddable
public class Users_RoomId implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "ID_room", nullable = false)
private String idRoom;
#Column(name = "user_id", nullable = false)
private int idUser;
}
Model Users_Room to join 2 Model Users and Room
#Entity
#Table(name ="bookroom")
public class Users_Room {
#EmbeddedId
private Users_RoomId usersroomId;
#ManyToOne
#MapsId("idRoom")
private Room room;
#ManyToOne
#MapsId("idUser")
private Users users;
#Column(name = "Bookday")
private String bookday;
Model Users and Room I used annotation #OneToMany
Model Users
#Entity
#Table(name = "users")
public class Users implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id", nullable = false)
private int id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "email")
private String email;
#Column(name = "pass")
private String pass;
#Column(name = "role")
private int role;
#OneToMany(mappedBy = "users")
private List<Users_Room> user;
Model Room
#Entity
#Table(name ="room")
public class Room implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID_room", nullable = false)
private String id;
#Column(name = "name_room", nullable = false)
private String name;
#Column(name = "Description")
private String describe;
#ManyToOne
#JoinColumn(name = "ID_status")
private Status status;
#Column(name = "room_image")
private String image;
public Room() {
super();
}
#ManyToOne
#JoinColumn(name = "ID_kind")
private KindRoom kind;
#OneToMany(mappedBy = "room")
private List<Users_Room> rooms;
This is my database
So I don't know how to insert a new bookroom with iduser,idroom and bookday with JPA repository.. It'necessary to write Query in JPARepository or We just need to use method save() to insert data
Thanks everyone
I had same problem and solved with following code. I used method save() to insert data. Following code is 'createRoom' method in 'RoomService.java'.
RoomService.java
private final RoomRepository roomRepository;
private final UserRoomRepository userRoomRepository;
private final UserRepository userRepository;
public RoomService(RoomRepository roomRepository, UserRoomRepository userRoomRepository, UserRepository userRepository) {
this.roomRepository = roomRepository;
this.userRoomRepository = userRoomRepository;
this.userRepository = userRepository;
}
#Transactional
public RoomDto createRoom(Long userId, Long chattingUserId) {
Room room = roomRepository.save(new Room());
room.addUserRoom(userRepository.findById(userId).orElseThrow(()->new NoSuchElementException("No User")));
room.addUserRoom(userRepository.findById(chattingUserId).orElseThrow(()->new NoSuchElementException("No User")));
userRoomRepository.save(new UserRoom(userRepository.findById(userId).orElseThrow(()->new NoSuchElementException("No User")),room));
userRoomRepository.save(new UserRoom(userRepository.findById(chattingUserId).orElseThrow(()->new NoSuchElementException("No User")),room));
RoomDto roomDto = RoomDto.of(room);
return roomDto;
}

[products_products_id])) must have same number of columns as the referenced primary key (products [categories_id,products_products_id])

i have error related to the hibernate query
Foreign key (FK_jipqfc4qahmxslbxjbln9cxpm:products [products_products_id])) must have same number of columns as the referenced primary key (products [categories_id,products_products_id])
i dont understand why it is i try lots of time but till now problem does not solve
Here is my oneToMany relation on categories pojo
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private int categories_id;
#Column
private String categories_image;
#Column
private int sort_order;
#Column
#Temporal(javax.persistence.TemporalType.DATE)
private Date date_added;
#Column
private Date last_modified;
#Column
private String categories_name;
public String getCategories_name() {
return categories_name;
}
public void setCategories_name(String categories_name) {
this.categories_name = categories_name;
}
#OneToOne(cascade = CascadeType.ALL, fetch= FetchType.LAZY)
#JoinTable(name="categories_description",joinColumns={
#JoinColumn(name = "categories_id",referencedColumnName="categories_id")})
private categories_description categories_description;
#OneToMany(cascade = CascadeType.ALL, fetch= FetchType.LAZY)
#JoinTable(name="products_to_categories",joinColumns={
#JoinColumn(name = "categories_id", referencedColumnName="categories_id")})
private Set<products_to_categories> products_to_categories;
#OneToMany(cascade = CascadeType.ALL, fetch= FetchType.LAZY)
#JoinTable(name="products",joinColumns={
#JoinColumn(name = "categories_id",referencedColumnName="categories_id")})
private Set<products> products;
and here is my products pojo
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column
private int products_id;
#Column
private int Category_id;
#Column
private int products_quantity;
#Column
private String products_model;
#Column
private String products_image;
#Column
private float products_price;
#Column
private Date products_date_added;
#Column
private Date products_last_modified;
#Column
private Date products_date_available;
#Column
private float products_weight;
#Column
private String products_status;
#Column
private int products_tax_class_id;
#Column
private int manufacturers_id;
#Column
private String products_type;
#OneToOne
#JoinColumn(name="products_id")
private products_description products_description;
#OneToOne
#JoinColumn(name="products_id")
private products_to_categories products_to_categories;
i want categories_id as a foregin key and also primary key inside products table
but while excuting i got this error .
please help i really appreciated.

Resources