Avoiding circular references in Hiberate - java

I have three domain classes.. Catalog, DeviceInventory, DeviceInventoryInfo..
Catalog class consists of all the devices being used, DeviceInventory class gives brief information about the costs initiated with the device and DeviceInventoryInfo gives the detailed description about the device inventory.
Device Inventory refers a field named modelId from Catalog class. Catalog class has one to many relationship with DeviceInventory. Whereas DeviceInventoryInfo class refers deviceInventory class with device inventory id having one to one relation. So whenever I call the insert web service, it says grammaticalSQLException. And this is what I get in my Console
Hibernate: select inventoryr0_.device_inventory_id as device_i1_7_, inventoryr0_.device_model_id as device_m4_7_, inventoryr0_.hospital_id as hospital2_7_, inventoryr0_.manufacturer_id as manufact3_7_, inventoryr0_.physical_status as physical5_7_, inventoryr0_.device_status as device_s6_7_ from device_inventory_register inventoryr0_ where inventoryr0_.device_inventory_id=?
Hibernate: select catalog0_.device_model_id as device_m1_4_0_, catalog0_.baseline_cost as baseline2_4_0_, catalog0_.device_category_id as device_c3_4_0_, catalog0_.device_classification_id as device_c4_4_0_, catalog0_.device_description as device_d5_4_0_, catalog0_.device_code as device_c6_4_0_, catalog0_.device_name as device_n7_4_0_, catalog0_.device_type_id as device_18_4_0_, catalog0_.equivalent_model_name as equivale8_4_0_, catalog0_.hospital_id as hospital9_4_0_, catalog0_.life_expectancy as life_ex10_4_0_, catalog0_.manufacturer_id as manufac11_4_0_, catalog0_.meter_type as meter_t12_4_0_, catalog0_.device_model_num as device_13_4_0_, catalog0_.replacement_cost as replace14_4_0_, catalog0_.device_status as device_15_4_0_, catalog0_.device_subcategory_id as device_16_4_0_, catalog0_.support_status as support17_4_0_, catalog0_.useful_life as useful_19_4_0_, categoryma1_.device_category_id as device_c1_5_1_, categoryma1_.device_category_description as device_c2_5_1_, categoryma1_.device_category as device_c3_5_1_, categoryma1_.hospital_id as hospital4_5_1_, categoryma1_.status as status5_5_1_, devicetype2_.device_type_id as device_t1_11_2_, devicetype2_.device_type_description as device_t2_11_2_, devicetype2_.device_type as device_t3_11_2_, devicetype2_.hospital_id as hospital4_11_2_, subcategor3_.device_subcategory_id as device_s1_10_3_, subcategor3_.device_category_id as device_c2_10_3_, subcategor3_.hospital_id as hospital3_10_3_, subcategor3_.status as status4_10_3_, subcategor3_.device_subcategory_description as device_s5_10_3_, subcategor3_.device_subcategory as device_s6_10_3_ from device_catalog catalog0_ inner join device_category_master categoryma1_ on catalog0_.device_classification_id=categoryma1_.device_category_id inner join device_type_master devicetype2_ on catalog0_.device_type_id=devicetype2_.device_type_id inner join device_subcategory_master subcategor3_ on catalog0_.device_subcategory_id=subcategor3_.device_subcategory_id where catalog0_.device_model_id=?
Hibernate: select inventoryr0_.s.no as s1_8_2_, inventoryr0_.date_of_acceptance as date_of_2_8_2_, inventoryr0_.account as account3_8_2_, inventoryr0_.baseline_cost as baseline4_8_2_, inventoryr0_.cost_to_date as cost_to_5_8_2_, inventoryr0_.device_inventory_id as device_i6_8_2_, inventoryr0_.stored_on_device as stored_o7_8_2_, inventoryr0_.hippa_data_id as hippa_da8_8_2_, inventoryr0_.date_of_installation as date_of_9_8_2_, inventoryr0_.date_of_launch as date_of10_8_2_, inventoryr0_.life_expectancy as life_ex11_8_2_, inventoryr0_.network_aware as network12_8_2_, inventoryr0_.network_connected as network13_8_2_, inventoryr0_.original_cost as origina14_8_2_, inventoryr0_.priority_id as priorit15_8_2_, inventoryr0_.date_of_purchase as date_of16_8_2_, inventoryr0_.date_of_receipt as date_of17_8_2_, inventoryr0_.replacement_cost as replace18_8_2_, inventoryr0_.risk_id as risk_id19_8_2_, inventoryr0_.skill_id as skill_i20_8_2_, inventoryr0_.transmitted_by_device as transmi21_8_2_, inventoryr0_.useful_life as useful_22_8_2_, inventoryr1_.device_inventory_id as device_i1_7_0_, inventoryr1_.device_model_id as device_m4_7_0_, inventoryr1_.hospital_id as hospital2_7_0_, inventoryr1_.manufacturer_id as manufact3_7_0_, inventoryr1_.physical_status as physical5_7_0_, inventoryr1_.device_status as device_s6_7_0_, catalog2_.device_model_id as device_m1_4_1_, catalog2_.baseline_cost as baseline2_4_1_, catalog2_.device_category_id as device_c3_4_1_, catalog2_.device_classification_id as device_c4_4_1_, catalog2_.device_description as device_d5_4_1_, catalog2_.device_code as device_c6_4_1_, catalog2_.device_name as device_n7_4_1_, catalog2_.device_type_id as device_18_4_1_, catalog2_.equivalent_model_name as equivale8_4_1_, catalog2_.hospital_id as hospital9_4_1_, catalog2_.life_expectancy as life_ex10_4_1_, catalog2_.manufacturer_id as manufac11_4_1_, catalog2_.meter_type as meter_t12_4_1_, catalog2_.device_model_num as device_13_4_1_, catalog2_.replacement_cost as replace14_4_1_, catalog2_.device_status as device_15_4_1_, catalog2_.device_subcategory_id as device_16_4_1_, catalog2_.support_status as support17_4_1_, catalog2_.useful_life as useful_19_4_1_ from device_inventory_register_info inventoryr0_ inner join device_inventory_register inventoryr1_ on inventoryr0_.device_inventory_id=inventoryr1_.device_inventory_id left outer join device_catalog catalog2_ on inventoryr1_.device_model_id=catalog2_.device_model_id where inventoryr0_.device_inventory_id=?
#Entity
#Table(name="device_catalog")
public class Catalog {
private Integer modelId;
private Integer hospitalId;
private Integer manufacturerId;
private String deviceCode;
private String modelNumber;
private String deviceName;
private String description;
private String equiModelName;
private Integer classificationId;
private Integer typeId;
private Integer categoryId;
private Integer subCategoryId;
private String meterType;
private Integer baselineCost;
private Integer replacementCost;
private Integer usefulLife;
private Integer lifeExpectancy;
private String supportStatus;
public enum Status{Active, Inactive}
#JsonBackReference
private ManufacturerMaster master;
private ClassificationMaster classificationMaster;
private DeviceTypeMaster deviceTypeMaster;
private CategoryMaster categoryMaster;
private SubCategoryMaster subCategoryMaster;
private Status status;
#JsonManagedReference
private Set<InventoryRegister> inventoryRegisters;
#Entity
#Table(name="device_inventory_register_info")
public class InventoryRegisterInfo {
private Integer serialNum;
private Integer deviceInventoryId;
private String account;
private Integer originalCost;
private Integer replacementCost;
private Integer costToDate;
private Integer baselineCost;
private Date purchaseDate;
private Date receiptDate;
private Date acceptanceDate;
private Date installationDate;
private Integer usefulLife;
private Integer lifeExpectancy;
private Date launchDate;
private String networkAware;
private String networkConnected;
private String deviceStored;
private String transmittedByDevice;
private Integer skillId;
private Integer priorityId;
private Integer hippaId;
private Integer riskId;
private InventoryRegister inventoryRegister;
#Entity
#JsonAutoDetect
#Table(name="device_inventory_register")
public class InventoryRegister {
private Integer deviceInventoryId;
private Integer modelId;
private Integer manufacturerId;
private Integer hospitalId;
private String physicalStatus;
private Status status;
#JsonBackReference
private Catalog catalog;
private InventoryRegisterInfo inventoryRegisterInfo;
So How could I stop unnecessary joins and circular references?

Did you try set circular references to null for each Entity before insert into DB?

Related

how to multily two fields from two different collections

I have two colections in mongodb sring boot:
public class StampOperation {
#Id
private String id;
private int addedQuantity;
private int previousQuantity;
private int remainingQuantity;
#JsonFormat(pattern="dd/MM/yyyy")
private Date operationDate;
#DBRef
private TaxStamp taxStamp;
}
public class TaxStamp
{
#Id
private String id;
private String name;
private double value;
private EType stampType;
private int globalInitialQuantity;
private int minimumThreshold;
}
is there any wa to multiply addedQuantity from StampOperation by value from TaxStamp ?
If I understand your question correctly, you want to know, how to multiply two values from two different objects.
double result = stampOperation.addedQuantity * taxStamp.value;
To do this operation, you need to have the referenced instances of both classes at hand. Also, the attributes which are supposed to be used (addedQuantity and value) need to be accessible. This could be done by e.g. marking them as public.

How to Convert MongoDB Query to Spring Data Query

I'm trying to convert the following Mongo query for use with Spring data.
db.product.aggregate([
{$unwind: '$barcodes'},
{$project: {
_id: 0,
productId: '$_id',
productTitle: '$title',
productVariation: '$variation',
barcode: '$barcodes'
}}])
This is what I've been trying so far. It returns the aggregation, but with null values:
UnwindOperation unwindOperation = Aggregation.unwind("barcodes");
ProjectionOperation projectStage = Aggregation.project().and("productId").as("_id").and("productTitle")
.as("title")
.and("productVariation").as("variation")
.and("barcodeTitle").as("barcodes.title")
.and("barcodeValue").as("barcodes.value")
.and("barcodeType").as("barcodes.type")
.and("codeStandard").as("barcodes.codeStandard")
.and("quantity").as("barcodes.quantity")
.and("status").as("barcodes.status");
SortOperation sortOperation = Aggregation.sort(Sort.by(Sort.Direction.DESC, "title"));
Aggregation agg = Aggregation.newAggregation(unwindOperation, projectStage, sortOperation);
AggregationResults<BarcodeAggregateList> results = mongoTemplate.aggregate(agg, "product", BarcodeAggregateList.class);
What it is returning:
The class I am mapping to (has getters/setters):
public class BarcodeAggregateList {
private String productId;
private String productTitle;
private String productVariation;
private String barcodeTitle;
private String barcodeValue;
private String barcodeType;
private String codeStandard;
private int quantity;
private String status;
}
Product class that the data is coming from:
public class Product implements Serializable {
private static final long serialVersionUID = -998149317494604215L;
private String id;
private String title;
private String description;
private String SKU;
private double cost;
private double retailPrice;
private String status;
private LocalDate launchDate;
private LocalDate discontinueDate;
private String discontinueReason;
private String salesChannel;
private List<Barcode> barcodes;
private ProductVariation variation;
private List<Supplier> supplier;
private Product parentProduct;
private boolean updateChildren;
private Label label;
private int secondaryStockLevel;
private int primaryStockLevel;
private Date createdDate;
private Date modifiedDate;
private List<Dimension> dimensions;
private boolean isDeleted = false;
}
Barcode class
public class Barcode {
private String type;
private String title;
private String value;
private String status;
private String codeStandard;
private int quantity;
}
I appreciate any help with this or resources to help me better understand how to perform these types of conversions.
For anyone trying to solve similar issues, I've found the following resources somewhat helpful:
https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.query
https://xpadro.com/2016/04/data-aggregation-with-spring-data-mongodb-and-spring-boot.html
https://www.tutorialspoint.com/get-fields-from-multiple-sub-documents-that-match-a-condition-in-mongodb
BarcodeAggregateList class fields are null because there is a minor issue in ProjectionOperation's and() and as() methods. The correct syntax is
Aggregation.project().and(SOURCE_FIELD).as(TARGET_FIELD)
You have written and("productId").as("_id") , which is wrong
You need to write this as and("_id").as("productId") , because source field is _id
complete code:
UnwindOperation unwindOperation = Aggregation.unwind("barcodes");
ProjectionOperation projectStage = Aggregation.project()
.and("_id").as("productId")
.and("title").as("productTitle")
.and("variation").as("productVariation")
.and("barcodes.title").as("barcodeTitle")
.and("barcodes.value").as("barcodeValue")
.and("barcodes.type").as("barcodeType")
.and("barcodes.codeStandard").as("codeStandard")
.and("barcodes.quantity").as("quantity")
.and("barcodes.status").as("status");
SortOperation sortOperation = Aggregation.sort(Sort.by(Sort.Direction.DESC, "productTitle"));
Aggregation agg = Aggregation.newAggregation(unwindOperation, projectStage, sortOperation);
AggregationResults<BarcodeAggregateList> results = mongoTemplate.aggregate(agg, "product", BarcodeAggregateList.class);

How to combine data from two reactive streams in project reactor?

I started using Project Reactor recently and I can't work out how to work with nested streams. I want to update data of outer Mono with some data of inner Mono.
#GetMapping("/search")
public Mono<Github> combineGithubData() {
WebClient client = WebClient.create("https://api.github.com");
Mono<Github> data = client.get().uri(URI.create("https://api.github.com/users/autocorrectoff")).retrieve().bodyToMono(Github.class);
data = data.map(s -> {
client.get().uri(URI.create("https://api.github.com/users/Kukilej")).retrieve().bodyToMono(Github.class).map(m -> {
s.setXXX(m.getName());
return m;
});
return s;
});
return data;
}
The field XXX is always returned as null, although I have set it to a value from inner Mono. I'm pretty sure this would work in RxJs. How do I make this work with Project Reactor?
edit:
the code of the Github class
import lombok.*;
#Getter #Setter
#Builder
#ToString
#NoArgsConstructor
#AllArgsConstructor
public class Github {
private String login;
private int id;
private String node_id;
private String avatar_url;
private String gravatar_id;
private String url;
private String html_url;
private String followers_url;
private String following_url;
private String gists_url;
private String starred_url;
private String subscriptions_url;
private String organizations_url;
private String repos_url;
private String events_url;
private String received_events_url;
private String type;
private boolean site_admin;
private String name;
private String company;
private String blog;
private String location;
private String email;
private String hireable;
private String bio;
private int public_repos;
private int public_gists;
private int followers;
private int following;
private String created_at;
private String updated_at;
private String XXX;
}
Your inner stream is not getting subscribed to. Either us flatMap, or better yet, use zip:
data
.zipWith(client.get().uri(...).retrieve().bodyToMono(Github.class))
.map(tuple2 -> {
//update tuple2.getT1() with m.getName() and return the updated tuple
return tuple2.mapT1(tuple2.getT1().setXXX(tuple2.getT2().getName()));
})
.map(tuple2 -> tuple2.getT1() //updated s);
zipWith() subscribes to the inner stream.

how can i combine 3 List of different object into one new object with Java 8

I have 3 objects List and i would like to combine it base on they unique key into one object List.
Since Loan depend on Account and Account depend on Bank
is there simple way without multiple looping for each object in java 8?
I know its better to do it in single query but wonder if there is something existing with Java 8 using List and combine it into one list.
public class Bank {
private String institution; //pk
private String transit; //pk
private String bankName;
}
public class Account {
private String institution; //pk
private String transit; //pk
private String accountNo; //pk
private String nameAccount;
}
public class Loan {
private String institution;//pk
private String transit;//pk
private String accountNo;//pk
private String serviceNo;//pk
}
// fusion object
public class CombineObject {
private String institution;
private String transit;
private String accountNo;
private String serviceNo;
private String nameAccount;
private String bankName;
}
List<Bank> lstBank = myListBank();
List<Account> lstAccount = myListAccount();
List<Loan> lstLoan = myListLoan();

How to find all data in DB using Hibernate?

I have following classes
#Entity
#Table(name="prm_user_permission")
public class UserPermission {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="prm_permission_id")
private Integer permissionId;
#Column(name="prm_permission_name")
private String permissionName;
#Column(name="prm_short_description")
private String shortDescription;
#Column(name="prm_description")
private String description;
#Column(name="prm_url")
private String permissionUrl;
#Column(name="prm_control")
private String control;
#Column(name="prm_create_user")
private Integer creatUser;
#Column(name="prm_parent_id")
private Integer parentId;
#Column(name="prm_system_id")
private Integer systemId;
// Getter and Setter
And my code is
public List<UserPermission> findAllBySystemId(int systemId) {
List<UserPermission> userPermission = criteria().setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.add(eq("UserPermission.systemId", systemId).list();
return userPermission;
}
Now i want to get all data from this (UserPermission) table by "systemId".If i pass systemId=1 then it should give all data where the column is '1'.
what is wrong in my code? while running it shows error like
org.hibernate.QueryException: could not resolve property: UserPermission of:
com.kgfsl.collections.core.security.models.UserPermission
Plz anybody help
What do the criteria() method returns?
And, try with systemId directly (eg: remove the UserPermission.)
Try with Restrictions.eq()
public List<UserPermission> findAllBySystemId(int systemId) {
List<UserPermission> userPermission = criteria().setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.add(Restrictions.eq("systemId", systemId)).list();
return userPermission;
}
Assuming that your criteria() method would be,
session.createCriteria(UserPermission.class)

Categories

Resources