How to count the iteration of lambda in Java streams - java-8

I have below solution with counter variable, is there any preferred way to get the counter of lambda iteration ?
class Employee {
String name;
int salary;
}
public class Calculator {
private static Integer counter;
public void method1() {
counter = 0; // Instead of this, is there any default counter ?
List<Employee> emp = getData()
List<Employee> updated = emp.stream().map(Calculator::increaseSalary).collect(Collectors.toList());
System.out.println("counter = " + counter);
}
private Employee increaseSalary(Employee emp) {
counter++;
emp.setSalary(50000);
return emp;
}
}

Related

How do I insert values of elements that are part of the EmbeddedId in JPA?

I have a case where I need to execute an insert statement via createNativeQuery. I have an entity list I'm looping through in order to set the properties accordingly from another bean class, and then persist that data to the oracle database.
The problem I am facing is persisting the data that is part of the embeddedId (item, loc, weekstart, type, forecastId, insertTS). I need to persist that data for the new records to be inserted into the database. When I try to set the values from the POJO bean to my set method for the properties of my entity bean, nothing happens. Below is my code for setting the values of the properties from the POJO bean to my entity bean, along with my persistence method and the insert query being executed:
Validation class where validation occurs beforehand (missing to get the point) that includes the setting of my entity properties from the POJO bean:
List <InsertPromoData> insertPromos = new ArrayList<InsertPromoData>();
promo.forEach(record -> {
if (record.getErrorList().size() == 0) {
rowsSuccessful++;
Util.writeSuccessToFile(templateCd, successFile, record, successFields);
try {
InsertPromoData insertData = new InsertPromoData();
insertData.getId().setItem(record.getItem());
insertData.getId().setLoc(record.getLoc());
insertData.getId().setWeekStart(record.getWeek_Start_Date());
insertData.setNumberOfWeeks(record.getNumber_Of_Weeks());
insertData.getId().setType(record.getType());
insertData.getId().setForecastId(record.getForecast_ID());
insertData.setQty(record.getUnits());
insertPromos.add(insertData);
}
catch (Exception e) {
logger.error("Error with setting insertPromolist from promo list values and the error is " + e.getMessage());
}
}
else {
if (rowsFailure == 0) {
Util.writeHeaderToFile(templateCd, errorFile);
}
rowsFailure++;
Util.writeErrorToFile(templateCd, errorFile, record, record.getErrorList());
}
});
errorFile.close();
successFile.close();
OracleImpl.insertPromoData(insertPromos);
POJO bean (promo is the variable representing this list of beans in validation class above):
public class PromoBean extends ErrorListBean
{
public String Item;
public String Loc;
public String Week_Start_Date;
public String Units;
public String Forecast_ID;
public String Type;
public String Number_Of_Weeks;
public String getItem() {
return Item;
}
public void setItem(String item) {
Item = item;
}
public String getLoc() {
return Loc;
}
public void setLoc(String loc) {
Loc = loc;
}
public String getWeek_Start_Date() {
return Week_Start_Date;
}
public void setWeek_Start_Date(String week_Start_Date) {
Week_Start_Date = week_Start_Date;
}
public String getNumber_Of_Weeks() {
return Number_Of_Weeks;
}
public void setNumber_Of_Weeks(String number_Of_Weeks) {
Number_Of_Weeks = number_Of_Weeks;
}
public String getType() {
return Type;
}
public void setType(String type) {
Type = type;
}
public String getForecast_ID() {
return Forecast_ID;
}
public void setForecast_ID(String forecast_ID) {
Forecast_ID = forecast_ID;
}
public String getUnits() {
return Units;
}
public void setUnits(String units) {
Units = units;
}
}
Embeddable class representing the composite primary key of the table:
#Embeddable
public class PromoID implements Serializable {
#Column(name = "ITEM")
private String item;
#Column(name = "LOC")
private String loc;
#Column(name = "WK_START")
private String weekStart;
#Column(name = "TYPE")
private String type;
#Column(name = "FCSTID")
private String forecastId;
#Column(name = "U_TIMESTAMP")
private String insertTS;
public PromoID() {
}
public PromoID (String item, String loc, String weekStart, String type, String forecastId, String insertTS) {
this.item = item;
this.loc = loc;
this.weekStart = weekStart;
this.type = type;
this.forecastId = forecastId;
this.insertTS = insertTS;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public String getWeekStart() {
return weekStart;
}
public void setWeekStart(String weekStart) {
this.weekStart = weekStart;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getForecastId() {
return forecastId;
}
public void setForecastId(String forecastId) {
this.forecastId = forecastId;
}
public String getInsertTS() {
return insertTS;
}
public void setInsertTS(String insertTS) {
this.insertTS = insertTS;
}
//hashcode and equals methods
Persistence Bean:
#Entity
#Table(name = "U_USER_PROMO")
public class InsertPromoData {
#EmbeddedId
private PromoID id;
#Column(name="NUMBER_OF_WEEKS")
String numberOfWeeks;
#Column(name="QTY")
String qty;
#Id
#AttributeOverrides(
{
#AttributeOverride(name = "item",column = #Column(name="ITEM")),
#AttributeOverride(name = "loc", column = #Column(name="LOC")),
#AttributeOverride(name = "weekStart", column = #Column(name="WK_START")),
#AttributeOverride(name = "type", column = #Column(name="TYPE")),
#AttributeOverride(name = "forecastId", column = #Column(name="FCSTID"))
}
)
public PromoID getId() {
return id;
}
public void setId(PromoID id) {
this.id = id;
}
public String getNumberOfWeeks() {
return numberOfWeeks;
}
public void setNumberOfWeeks(String numberOfWeeks) {
this.numberOfWeeks = numberOfWeeks;
}
public String getQty() {
return qty;
}
public void setQty(String qty) {
this.qty = qty;
}
}
DAO class method to execute the update (entitymanagerfactory emf already initialized):
public static void insertPromoData(List<InsertPromoData> insertData) {
logger.debug("Execution of method insertPromoData in Dao started");
System.out.println("Size of the insertData list is " + insertData.size());
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
System.out.println("Beginning transaction for insertPromoData");
Query query = em.createNativeQuery(env.getProperty("insertPromoUploadData"));
for (InsertPromoData promoData : insertData) {
query.setParameter("item", promoData.getId().getItem());
query.setParameter("location", promoData.getId().getLoc());
query.setParameter("wkStart", promoData.getId().getWeekStart());
query.setParameter("numberOfWeeks", promoData.getNumberOfWeeks());
query.setParameter("type", promoData.getId().getType());
query.setParameter("fcstId", promoData.getId().getForecastId());
query.setParameter("quantity", promoData.getQty());
query.executeUpdate();
}
em.getTransaction().commit();
}
catch(Exception e) {
logger.error("Exception in beginning transaction");
e.printStackTrace();
}
finally {
em.clear();
em.close();
}
logger.debug("Execution of method insertPromoData in Dao ended");
}
Query in properties file:
insertPromoUploadData = INSERT INTO {h-schema}U_USER_PROMO (ITEM, LOC, WK_START, NUMBER_OF_WEEKS, TYPE, FCSTID, QTY, U_TIMESTAMP) VALUES (:item, :location, TO_DATE(:wkStart,'MM DD YYYY'), :numberOfWeeks, :type, :fcstId, :quantity, SYSDATE)
My list size from my DAO class is returning as 0 once I begin the transaction and not sure why it is empty. Is there a reason that it is empty? I'm trying to persist each of the fields to the database (including the composite key fields) via insert query. Any help appreciated.
After looking into this for hours, I finally came to the conclusion that the simplest way to executeUpdate() without running into issues due to my current #EmbeddedId/#Embeddable logic was to change it to use #IdClass for my composite PK class, and annotate the fields from the PK in my entity with #Id. This allowed my data to be persisted to the database. Another slight difference was adding the insertTS in my entity class and annotating with #Id and generating getters/setters. This was necessary for JPA to recognize all the properties being referenced that I am wanting to persist, though I am persisting insertTS using SYSDATE function from the oracle DB instead of utilizing the get/set methods and setting to the current time from the java side.
I am sure there is a way to use #EmbeddedId/#Embeddable logic and be able to persist the fields that are part of the EmbeddedId, however, this I found to be a more simplistic way of doing it without further complexity in the code.

JPA - Get values from fields in other entities in a Controller class

I have two entities: Room and Service. I also have a method in Logic class that i want to use in ServiceController class. Other classes are irrelevant.
room.getBeds() always returns 0, default int value.
Room entity:
#Entity
public class Room {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int room_id;
private int beds;
private int number;
public Room() {
}
public Room(int beds, int number) {
this.beds = beds;
this.number = number;
}
public int getRoom_id() {
return room_id;
}
public void setRoom_id(int room_id) {
this.room_id = room_id;
}
public int getBeds() {
return beds;
}
public void setBeds(int beds) {
this.beds = beds;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
Service entity:
#Entity
public class Service {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int service_id;
#JsonFormat(pattern = "dd/MM/yyyy", timezone = "Europe/Berlin")
private Date arrival_at;
#JsonFormat(pattern = "dd/MM/yyyy", timezone = "Europe/Berlin")
private Date departure_at;
private int meals;
private int guest_id;
private double price;
public int getService_id() {
return service_id;
}
public void setService_id(int service_id) {
this.service_id = service_id;
}
public Date getArrival_at() {
return arrival_at;
}
public void setArrival_at(Date arrival_at) {
this.arrival_at = arrival_at;
}
public Date getDeparture_at() {
return departure_at;
}
public void setDeparture_at(Date departure_at) {
this.departure_at = departure_at;
}
public int getMeals() {
return meals;
}
public void setMeals(int meals) {
this.meals = meals;
}
public int getGuest_id() {
return guest_id;
}
public void setGuest_id(int guest_id) {
this.guest_id = guest_id;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Service controller:
#RestController
public class ServiceController {
#Autowired
ServiceRepository serviceRepository;
private Logic logic = new Logic();
private Room room = new Room();
//CREATE
#PostMapping("/services")
public int createService(#RequestBody Service service) {
service.setPrice(logic.calculatePrice(service.getArrival_at(), service.getDeparture_at(), room.getBeds(), service.getMeals()));
return serviceRepository.save(service);
}
}
How to get the correct value from room.getBeds() getter?
Lerius you are just making a new object of Room Entity and are not populating any values from your Database to that object
that is the reason why it is taking room.getBeds(); as 0(i.e default value for int)
Try Populating DB values to your object after that you will be able to get the value of getBeds();

Wrap collections in Value Objects

I have the following entities:
public class ComplexEntity {
public List<TenderLocation> tenderList;
public ComplexEntity(List<TenderLocation> tenderList) {
this.tenderList = tenderList;
}
}
public class TenderLocation {
public String location;
public List<TenderAirline> tenderAirlines;
public TenderLocation(String location, List<TenderAirline> tenderAirlines) {
this.tenderAirlines = tenderAirlines;
this.location = location;
}
}
public class TenderAirline {
public int ID;
public String name;
public TenderAirline(int ID, String name) {
this.ID = ID;
this.name = name;
}
}
And the following test for comparing two ComplexEntiey:
public class ComplexObjectGraphComparisonExample {
#Test
public void shouldCompareTwoComplexObjects() {
// given
Javers javers = JaversBuilder.javers().build();
// Construct test data
// ComplexEntity:
// - List<TLocation>
// TLoation:
// - location: String
// - List<TAir>
// TAir:
// - int ID
// - String Name
int locations = 3;
List<TenderLocation> tenderLocationsBase = new ArrayList<TenderLocation>(locations);
List<TenderLocation> tenderLocationsRef = new ArrayList<TenderLocation>(locations);
for (int j = 0; j < locations; ++j) {
int airlines = 10;
List<TenderAirline> tenderAirlinesBase = new ArrayList<TenderAirline>(airlines);
List<TenderAirline> tenderAirlinesRef = new ArrayList<TenderAirline>(airlines);
for (int i = 0; i < airlines; ++i) {
tenderAirlinesBase.add(new TenderAirline(i, "Airline" + i));
tenderAirlinesRef.add(new TenderAirline(i, "Airline" + i));
}
tenderLocationsBase.add(new TenderLocation("BV" + j, tenderAirlinesBase));
tenderLocationsRef.add(new TenderLocation("BV" + j, tenderAirlinesBase));
}
ComplexEntity baseEntity = new ComplexEntity(tenderLocationsBase);
ComplexEntity referenceEntity = new ComplexEntity(tenderLocationsRef);
// when
Diff diff = javers.compare(baseEntity, referenceEntity);
assertThat(diff.getChanges()).hasSize(0);
// Change a single small thing
referenceEntity.tenderList.get(1).location = "Difference_1";
// then there is a single change detected
diff = javers.compare(baseEntity, referenceEntity);
assertThat(diff.getChanges()).hasSize(1);
// there should be one change of type {#link ValueChange}
ValueChange change = diff.getChangesByType(ValueChange.class).get(0);
assertThat(change.getPropertyName()).isEqualTo("location");
assertThat(change.getLeft()).isEqualTo("BV1");
assertThat(change.getRight()).isEqualTo("Difference_1");
// do another change
referenceEntity.tenderList.get(1).tenderAirlines.get(1).name = "Difference_2";
// second difference is not detected, failing the commented test
diff = javers.compare(baseEntity, referenceEntity);
assertThat(diff.getChanges()).hasSize(2);
System.out.println(diff);
}
}
At comparison my second change is not identified because the compare method is not comparing in depth my lists.
I have read here
http://www.atetric.com/atetric/javadoc/org.javers/javers-core/1.3.4/org/javers/core/Javers.html
that if I "wrap collections in some Value Objects" the deep comparing of the collection is possible.
My question is, How exactly I can wrap my collection into Value Objects?
You can wrap the object something like below:
public class Wrapper
{
private final WrappedObject obj;
public Wrapper (WrappedObject obj)
{
this.obj = obj;
}
}
What is wrong in you code is mapping, you didn't do it at all. You should map your entities as Entities using #Id annotation:
public class TenderLocation {
#Id
public String location;
...
public class TenderAirline {
#Id
public int ID;
public String name;
...
Otherwise, JaVers maps your classes as Value Objects (objects without identity) which gives you limited diff experience.

Comparing dates in ascending and descending order in arrayList not working

I have an array of email objects. I need to sort them by two fields. the first field is by subject, which i have working, and the other is by date which I cannot get. I tried a bunch of other people's solutions but nothing seems to work. Here is an excerpt of my code:
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Comparator;
import java.util.Date;
public class Email implements Comparable{
private String to;
private String cc;
private String bcc;
private String subject;
private String body;
private GregorianCalendar timestamp; //time that email was created
//constructors and getters and setters (besides timeStamp) omitted to save space
public Date getTimestamp() {
return timestamp.getTime();
}
public void setTimestamp(GregorianCalendar timestamp) {
this.timestamp = timestamp;
}
//This works
public static Comparator<Email> emailSubjectComparatorAscending = new Comparator<Email>(){
public int compare(Email e1, Email e2) {
String EmailSubject1 = e1.getSubject().toLowerCase();
String EmailSubject2 = e2.getSubject().toLowerCase();
return EmailSubject1.compareTo(EmailSubject2);
}
};
//This works
public static Comparator<Email> emailSubjectComparatorDescending = new Comparator<Email>(){
public int compare(Email e1, Email e2) {
String EmailSubject1 = e1.getSubject().toLowerCase();
String EmailSubject2 = e2.getSubject().toLowerCase();
return EmailSubject2.compareTo(EmailSubject1);
}
};
//This doesn't work
public static Comparator<Email> emailDateComparatorAscending = new Comparator<Email>(){
#Override
public int compare(Email o1, Email o2) {
if(o1.getTimestamp().equals(o2.getTimestamp()))
return 0;
if(o2.getTimestamp().before(o1.getTimestamp()))
return 1;
else
return -1;
}
};
//This doesn't work
public static Comparator<Email> emailDateComparatorDescending = new Comparator<Email>(){
#Override
public int compare(Email o1, Email o2) {
if(o1.getTimestamp().equals(o2.getTimestamp()))
return 0;
if(o1.getTimestamp().before(o2.getTimestamp()))
return 1;
else
return -1;
}
};
#Override
public String toString(){
return("To: " + to + "\nCC: " + cc + "\nBCC: " + bcc + "\nSubject: " + subject + "\n" + body);
}
#Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
}
here is the part of my other class, in which I call these sorting methods:
import java.util.*;
public class Folder{
private ArrayList<Email> emails; //initialize?
private String name;
private String currentSortingMethod; //default = descending
public Folder(String name) {
super();
this.name = name;
currentSortingMethod = "sortByDateDescending";
emails = new ArrayList<Email>(); //instantiate the arrayList
}
//omitted getters, setters and other irrelevant methods
//This works
public void sortBySubjectAscending(){
Collections.sort(emails, Email.emailSubjectComparatorAscending);
currentSortingMethod = "sortBySubjectAscending";
}
//This works
public void sortBySubjectDescending(){
Collections.sort(emails, Email.emailSubjectComparatorDescending);
currentSortingMethod = "sortBySubjectDescending";
}
//This doesn't work
public void sortByDateAscending(){
Collections.sort(emails, Email.emailDateComparatorAscending);
currentSortingMethod = "sortByDateAscending";
}
//This doesn't work
public void sortByDateDescending(){
Collections.sort(emails, Email.emailDateComparatorDescending);
currentSortingMethod = "sortByDateDescending";
}
I am really confused with this and I have tried so many different ways and none work. If anyone could explain how to make this work I would appreciate it greatly

'EmployeeDetails' does not implement interface member 'System.ComponentModel.INotifyPropertyChanged.PropertyChanged'

I am trying to implement Inotifypropertychange interface, such as
public class EmployeeDetails:INotifyPropertyChanged
{
private int employeeID;
public int EmployeeID
{
get { return employeeID; }
set { employeeID = value; this.NotifyPropertyChanged("EmployeeId"); }
}
private string employeeName;
public string EmployeeName
{
get { return employeeName; }
set { employeeName = value; this.NotifyPropertyChanged("EmployeeName"); }
}
private decimal salary;
public decimal Salary
{
get { return salary; }
set { salary = value; this.NotifyPropertyChanged("Salary"); }
}
public event PropertyChangedEventHandler propertychange;
public void NotifyPropertyChanged(string name)
{
if (propertychange != null)
propertychange(this, new PropertyChangedEventArgs(name));
}
public EmployeeDetails(int employeeId, string employeeName, decimal salary)
{
EmployeeID = employeeID;
EmployeeName = employeeName;
Salary = salary;
}
public EmployeeDetails()
{
// TODO: Complete member initialization
}
}
while debuging, it shows the following error:
'EmployeeDetails' does not implement interface member 'System.ComponentModel.INotifyPropertyChange
what particular code i missing, please help
i have included the system.component assembly.
You can use this code
public class EmployeeDetails : INotifyPropertyChanged
{
...
}
And you right click on INotifyPropertyChanged, firstly you execute resolve reference and select implement interface

Resources