I ran into a problem while creating a project. If I use properties (get;set;), the android application crashes at the point of assigning a value to the property.
For example: I created a clean xamarin project to remove the influence of my code.
Property in my class:
public class Item
{
public string Id
{
get { return Id; }
set { Id = value; }
}
}
Property use:
public AboutPage()
{
Item gg = new Item();
gg.Id = "test";
InitializeComponent();
}
App crashes at line:
set { Id = value; }
Error not show.
Error
Help. This is the first time I've seen this. I have downgraded the platform. Used clean projects. What am I doing wrong?
UPD: link to my solution
You could try to change the property like below:
public class Item
{
public string Id { get; set; }
}
or
public class Item
{
private string id;
public string Id
{
get { return id; }
set { id = value; }
}
}
when you impement the INotifyPropertyChanged interface:
public class Item : INotifyPropertyChanged
{
private string id;
public string Id
{
get { return id; }
set { id = value; OnPropertyChanged("Id"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
When you do this:
public string Id
{
get { return Id; }
set { Id = value; }
}
You are essentially creating an infinite loop. This is why your App crashes. You are infinitely calling the setter.
Instead you would either make it an auto property:
public string Id { get; set; }
or add a backing field for the property:
private string _id;
public string Id
{
get => _id;
set => _id = value;
}
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.
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();
In the below example I have a department with many cases. I need to get the latest case from the department where the sort order is based on udpatedTime (if udpatedTime is null have to consider createDate) and have to return the first item in the list that is the most recent one (either created or updated). For the newly created case, the updatetime would be null until a case is updated.
public class Case{
Long id;
String number;
String status;
LocalDateTime createDate;
String createdBy;
LocalDateTime udpatedTime;
String updatedBy;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public LocalDateTime getCreateDate() {
return createDate;
}
public void setCreateDate(LocalDateTime createDate) {
this.createDate = createDate;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public LocalDateTime getUdpatedTime() {
return udpatedTime;
}
public void setUdpatedTime(LocalDateTime udpatedTime) {
this.udpatedTime = udpatedTime;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}
}
public class Department {
String id;
List<Case> allCases;
Case latestCase;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Case> getAllCases() {
return allCases;
}
public void setAllCases(List<Case> allCases) {
this.allCases = allCases;
}
public Case getLatestCase() {
if (getAllCases().isEmpty()) {
return null;
}
getAllCases().sort(new Comparator<Case>() {
#Override
public int compare(Case o1, Case o2) {
if (o1.getUdpatedTime() != null) {
o1.getUdpatedTime().isAfter(o2.getUdpatedTime());
} else if (o2.getUdpatedTime() != null) {
o1.getUdpatedTime().isAfter(o2.getUdpatedTime());
}
return 0;
}
});
return null;
}
}
You do not need to sort the list to get the most recent entry. Just use max:
import static java.util.Comparator.comparing;
getAllCases().stream()
.max(comparing(
c -> c.getUpdatedTime() == null ? c.getCreatedTime() : c.getUpdatedTime()
));
In java 9, you can replace the key extractor with c -> Objects.requireNonNullElse(c.getUpdatedTime(), c.getCreatedTime())
or c -> Objects.requireNonNullElseGet(c.getUpdatedTime(), c::getCreatedTime) (but that's probably overkill)
I have the following class that I take as input in my Resource
#JsonIgnoreProperties(ignoreUnknown = false)
public class InputRequest {
#NotEmpty
private List<String> names;
private DateTime startDate;
private DateTime endDate;
#ValidationMethod(message="startDate should be less than endDate")
public boolean isValidDates() {
return startDate.isBefore(endDate);
}
#ValidationMethod(message = "one of the names is not valid")
public boolean isValidNames() {
//do something
}
public List<String> getNames() {
return names;
}
public void setNames(List<String> names) {
this.names = names;
}
public DateTime getStartDate() {
return startDate;
}
public void setStartDate(DateTime startDate) {
this.startDate = startDate;
}
public DateTime getEndDate() {
return endDate;
}
public void setEndDate(DateTime endDate) {
this.endDate = endDate;
}
}
The resource class is as follows
public Response getData(#Auth String userId, #Valid InputRequest request) {
However, the following input is not causing any exceptions
{"names":["somename"],"startDate":1427155200000,"endDate":1427846400000, "x":"a"}
Can someone tell me what I am doing wrong here?
EDIT: Also if I send the following instead, its passing through
{"names":["somename"],"startDate":1427155200000}
I want it to fail if something field is missing
bootstrap.getObjectMapperFactory().enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
worked for me