i'm using java, for example, i have 2 tables staff(id, name, status_id, company_id) and company(id, name), the corresponding entity looks like:
public class Staff {
private Integer id;
private String name;
private Integer statusId;
private Integer companyId;
private Company company;
}
public class Company {
private Integer id;
private String name;
private List<Staff> staffList;
}
for status_id of table staff, 0 means New, 1 represents Active and 2 stands for Inactive.
I need to show New, Active or Inactive on html page/excel when describe a staff status rather than 0, 1 or 2.
And I have a StaffDto:
public class StaffDto {
private Integer id;
private String name;
private Integer statusId;
private String companyName;
}
my questions are:
the statusName(New/Active/Inactive) should be in StaffDto, such that there is no need to calculate status name according to statusId on each client, right?
what is a good practice to get statusName base on statusId?
I should write code like
public class StaffDto {
private Integer statusId;
private String statusName;
public String getStatusName() {
switch(statusId) {
case 0: return "New";
case 1: return "Active";
case 2: return "Inactive";
}
}
}
is this a good practice? or something else(e.g. enum) is better?
if the logic of getting status name is added in StaffDto, what if there is another dtoj(e.g. ADto) also need to show status name, then I have to re-write this logic in ADto?
what if one client need to show New, Active or Inactive, while another client need to show A, B or C or something else, then what should I return in StaffDto? do I still return New, Active or Inactive in StaffDto, and other client need to calculate N, A or I base on statusId on their client? or should I return something else to client instead of xxxDto?
I too would go for enum as you mentioned, bind the status code to the name
then, you do not have to rewrite the logic in DTOs, Make your model have the enum rather than code or name
enum can have its own methods like getShortName for different representations
enum Status {
NEW(0), Active(1), InActive(2);
private final int code;
Status(int code) {
this.code = code;
}
public String getShortName() {
return this.name().substring(0, 1).toUpperCase();
}
public int getCode() {
return code;
}
}
Related
Sorry for bad english.
I currently use dto for request body mapping,
Spring can not know input is null or not received, because both situation is just null.
As an example, Like this.
// dto
public class UpdateDto {
private String name;
private Integer price;
}
// entity
public class Product {
#Id
#GeneratedValue
private Long id;
#Column(nullable = true)
private String name;
#Column(nullable = true)
private Integer price;
}
I solved in string case using empty string. When empty string received, update this field to null. Because most of case empty string can treated as null.
// update name
if (updateDto.getName() != null) {
if (updateDto.getName() == "") {
// set name to null
} else {
// just update to getName() value
}
}
// update price
// when i set to null?
However integer case, I don't know how can i solve this problem.
Anything good idea?
you can use primitive data type int and set nullable as false since null doesn't make sense for numbers
use primitive data type for price in both entity and dto
Entity:
#Column(nullable = false)
private int price;
DTO:
private int price;
I found the easiest solution.
related link(In korean): https://www.it-gundan.com/ko/java/spring-rest-controller%EC%97%90%EC%84%9C-%EB%B6%80%EB%B6%84-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8%EC%97%90-%EB%8C%80%ED%95%B4-null-%EA%B0%92%EA%B3%BC-%EC%A0%9C%EA%B3%B5%EB%90%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EA%B0%92%EC%9D%84-%EA%B5%AC%EB%B3%84%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95/827265839/
the solution is, add dirty check boolean flag in setter.
in case of above,
// dto
public class UpdateDto {
private String name;
private Integer price;
private Boolean isPriceDirty;
// when setter setPrice,
public void setPrice(Integer price) {
this.price = price;
this.isPriceDirty = true;
}
}
then, output can set null only when dirty is true.
I have an object extending SugarRecord that looks like this:
public class SavedDraft extends SugarRecord {
private String name;
private String difficulty;
private int sport_id;
private LocalActivity localActivity;
public SavedDraft() {
}
public SavedDraft(String name, String difficulty, int ID, LocalActivity localActivity) {
this.name = name;
this.difficulty = difficulty;
this.sport_id = ID;
this.localActivity = localActivity;
}
}
The problem is that I always get a null object when I try to get the localActivity object from the database (see: SavedDraft.findById(SavedDraft.class, 1).getLocalActivity()), and I'm just wondering if it's possible to save objects as parameters in SugarORM at all.
This would be a relationship and you would need the LocalActivity to extend SugarRecord also.
See the documentation of Book and Author: http://satyan.github.io/sugar/creation.html
I'm currently working on this code, I want to pass an ID to a member function to get the object.
public class Car {
private int _ID;
private String name;
private String model;
Car(int _id, String name, String model){
this._ID = _id;
this.name = name;
this.model = model;
}
....
public static Car getCar(int _id){
Car mCar;
//TODO: Algo to get car
return mCar;
}
}
Is there any way I can get the object in this way?
Any help is appreciated!
Thank You!
You'll need to keep a Map of objects by key. Here's one way to do it:
public class Car {
private int _ID;
private String name;
private String model;
Car(int _id, String name, String model){
this._ID = _id;
this.name = name;
this.model = model;
carsById.put(_id, this); // <-- add to map
}
....
private static Map<Integer, Car> carsById = new HashMap<>();
public static Car getCar(int _id){
return carsById.get(_id);
}
}
There's no predefined way to do that. You'd have to have Car or something else maintain a Map<Integer,Car> or similar of cars. This would usually be best done not in Car itself, but in the code using it.
Unless you have a list (or map or tree or anything else suitable) of created Car, it's not possible with your current code only. A good practice is to separate this list out of Car class, maintained elsewhere. But if you insist, shmosel provides one way.
I tried to fill DB tables with random data and through Hibernate.
But my code fill incompatible data into tables (not exactly incompatible it is index of this element declared at enum, for ex: at ApartmentState - FREE is first element it set to appropriate column it index - 0. But I want to put or FREE as enum or as string).
I couldn't figure out why exactly this happen.
Here is code snippet:
private List<Apartment> generateApartments() {
for (int i = 1; i <= 3; i++) {
for (int j = 2; j <= 5; j++) {
Apartment apartment = new Apartment();
// fill apartment
apartment.setRoomName(generateRoomName());
apartment.setPricePerHour(generatePrice());
apartment.setApartmentState(FREE);
apartment.setRating(getDesiredRating(j));
apartment.setSleepPlaces(getDesiredPlaces(i));
apartment.setActive(true);
// save apartment
apartments.add(apartment);
}
}
return apartments;
}
private Apartment.SleepPlaces getDesiredPlaces(int i) {
switch (i) {
case 1:
return ONE_PLACE;
case 2:
return TWO_PLACES;
case 3:
return THREE_PLACES;
}
return ONE_PLACE;
}
private Apartment.StarRating getDesiredRating(int j) {
switch (j) {
case 2:
return TWO_STARS;
case 3:
return THREE_STARS;
case 4:
return FOUR_STARS;
case 5:
return FIVE_STARS;
}
return TWO_STARS;
}
I need to fill at table some enum values, as rating (2, 3, 4) and sleep places (1, 2..).
But this puts some wrong data into table.
Here is content at workbench:
Why it puts only index, not as string or as enum.
How can I recovering this at desired value, in the future.
Here is snippet from Apartment class:
#Entity
#Table(name = "Apartments")
public class Apartment extends AbstractEntity implements Comparable<Apartment> {
private Integer id;
private String roomName;
private Double pricePerHour;
private ApartmentState apartmentState;
private StarRating rating;
private SleepPlaces sleepPlaces;
private Boolean active;
public enum ApartmentState {
FREE, REQUESTED, BOOKED, LIVED, CLEANING, PROCESSING
}
public enum StarRating {
TWO_STARS("2 stars"), THREE_STARS("3 stars"), FOUR_STARS("4 stars"), FIVE_STARS("5 stars");
private String description;
private StarRating(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
public enum SleepPlaces {
ONE_PLACE("1 person"), TWO_PLACES("2 persons"), THREE_PLACES("3 persons"), FOUR_PLACES("4 persons");
private String count;
private SleepPlaces(String count) {
this.count = count;
}
public String getCount() {
return count;
}
}
For me the best is to put enum as enum (possibly at MySql workbench) or as a string (and use name() and valueOf() from Enum class).
But how to implement it with hibernate.
How to solve this trouble?
You can add following enumeration, to indicate you want the String representation to be persisted :
#Enumerated(EnumType.STRING)
private ApartmentState apartmentState;
Use this annotation at field level:
#Enumerated(EnumType.STRING)
I also had to add
#Embeddable to the java enum
#Embeddable
public enum ApartmentState {
FREE, REQUESTED, BOOKED, LIVED, CLEANING, PROCESSING
}
after messing around with parsing a JSON response with GSON for a day, I finally figured out how to get my javabeans right in order to extract my data from the response. This is the layout of my nested classes and lists:
public class LocationContainer {
public class paging {
private String previous;
private String next;
}
private List<Datas> data;
public class Datas {
private String message;
private String id;
private String created_time;
public class Tags {
private List<Data> datas;
public class Data {
private String id;
private String name;
}
}
public class Application {
private String id;
private String name;
}
public class From {
private String id;
private String name;
}
public class Place {
private String id;
private String name;
public class Location {
private int longitude;
private int latitude;
}
}
}
}
Now I am trying to get a hold of the name string inside the place class and the created_time string, but since I am quite a noob, I can't seem to figure it out.
I was able to extract the created_time string by using
String time = gson.toJson(item.data.get(1).created_time);
However using
String name = gson.toJson(item.data.get(1).Place.name);
doesnt work.
The item class is an instance of LocationContainer filled with the output from GSON.
Any pointers would be greatly appreciated.
created_time is a member variable of Data, so your first line is fine.
However, Place is not a member variable, it's just a class definition. You probably need to instantiate a member variable inside your Data class, e.g.:
private Place place;