Add key and description of Enum in database - java

I have a little problem in java and I didn't find any solution.
In class CustomerOrder I have a list of Enum type. I want to store in database key and description of enum. How can I do to save key and description?
Enum:
#Entity
public enum MenuList{
SOUP(15.00),
PIZZA_CHEESE_S(20.00),
PIZZA_CHEESE_M(30.00),
KEBAB(15.00),
PASTA(18.00),
FRENCH_FRIES(10.00),
STEAK(25.00),
SAUCE(3.00);
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
......}
Class customer order
#Entity
public class CustomerOrder {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private Integer noOfTable;
#OneToMany(mappedBy="customerOrder")
#Enumerated(EnumType.STRING)
private List<MenuList> productsOrdered;
private Double totalOrder;
#ManyToOne
....}

Take a look at AttributeConverter!
https://docs.oracle.com/javaee/7/api/javax/persistence/AttributeConverter.html
class MenuListConverter implements AttributeConverter<MenuList, String> {
private final static String DELIMITER = ":";
#Override
public String convertToDatabaseColumn(final MenuList menu) {
return String.format("%s%c%s", menu.name(), DELIMITER, "put your id here");
}
#Override
public String convertToEntityAttribute(final String value) {
if( value == null || value.isEmpty()) {
return null;
}
final String name = value.split(DELIMITER)[0];
return MenuList.valueOf(name);
}
}
Then, in your entity,
#Column(name = "MENU")
#Convert(converter = MenuListConverter.class)
private MenuList menu;

You could probably use a HashMap. Something like
HashMap<String, String> map = new HashMap<String, String>() {{
put("SOUP", "Classic noodle Soup");
put("FRENCH_FRIES", "Regular french fries");
}};
then you can get the descriptions with map.get(KEY);

Related

Make an object with sql table's datatype

This might be very silly question but,
I have a hashmap<string, list<string>> and I am putting the values in the hashmap. Now the issue is that the variables of hashmap are the variables for the sql data table. Is there any way in which I can simply use the class of the sql data table rather than creating a local class and making a constructor?
public class Student {
#Id
#Column(name = "id", nullable = false)
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
public Long getId() { return this.id; }
#Column(name = "studentName1")
public String studentName1;
#Column(name = "studentName2")
public String studentName2;
#Column(name = "studentName3")
public String studentName3;
}
import java.util.*;
public class ConcurrentHashMapExample {
public static void main(String[] args)
{
// Creating ConcurrentHashMap
Map<String, List<String>>
my_cmmap = new ConcurrentHashMap<String, List<String>>();
// Adding elements to the map
// using put() method
my_cmmap.put("1", Arrays.asList("2","3"));
my_cmmap.put("2", Arrays.asList("4","5"));
}
}
Now, mu_cmmap.values() will give the list<string>. Is there any efficient way to do this?

Hibernate: Set property field to static final object instance

I would like to create static final instances in my application that I can use to drive logic. An example of this would be:
public class ChargeStatusType {
private String code;
private String value;
private ChargeStatusType(String code, String value){
this.code = code;
this.value = value;
}
public static final ChargeStatusType APPROVED = new ChargeStatusType("APPROVED", "Approved");
public static final ChargeStatusType COMPELTED = new ChargeStatusType("COMPLETED", "Completed");
public static final ChargeStatusType CANCELLED = new ChargeStatusType("CANCELLED", "Cancelled");
public static final ChargeStatusType FAILED = new ChargeStatusType("FAILED", "Failed");
}
which is then used in
#Entity
#Table(name="charge_result")
public class ChargeResult extends RepresentationModel<ChargeResult> {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
private ChargeStatusType chargeStatusType;
I am having issues saving ChargeResult as Spring / Hibernate does not know what to do with ChargeResult.ChargeStatusType.
Besides converting ChargeStatusType to an enum, is there a way to persist ChargeResult with a ChargeStatusType?
Instead of declaring chargeStatusType as a type of ChargeStatusType you can declare it as a String and persist that String then get the value using a static map like so
#Entity
#Table(name="charge_result")
public class ChargeResult extends RepresentationModel<ChargeResult> {
private static final Map<String, String> chargeStatusType;
static{
chargeStatusType = new HashMap<>();
chargeStatusType.put("APPROVED", "Approved");
chargeStatusType.put("COMPLETED", "Completed");
chargeStatusType.put("CANCELLED", "Cancelled");
chargeStatusType.put("FAILED", "Failed");
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
#Column
private String chargeStatusKey;
public String getChargeStatusKey(){
return chargeStatusType.get(chargeStatusKey);
}

How to set and get value from the composite key

I am trying to set the value cid in student class using SubjectMark->private String cid;
How to set and get value in my controller.
Entity's and controller method below:
#Entity
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private SubjectMark id;
private String fullName;
private Integer totalMarks;
private Double percentage;
private String grade;
//Setters and getters
}
//Composit class
#Embeddable
public class SubjectMark implements Serializable {
//Composit key
private String cid;
//Setters and getters
}
In my controller I try to set value like this:
#RequestMapping(value="getstdata",method=RequestMethod.GET)
#ResponseBody
public String getstdata(#RequestParam(value="cid")String cid){
//Some code
try{
Student st=new Student();
st.getId().setCid(cid);//Set value like this but it is getting null pointer exception
//some code
//retuen some value
}
Please help me!
1st part of question:
I am trying to set the value cid in student class using SubjectMark->private String cid; How to set and get value in my controller.
#Entity
#Table
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private SubjectMark subjectMarkId;
private String otherField;
// setters, getters
}
//Composite class
#Embeddable
public class SubjectMark implements Serializable {
private String cId;
// setter, getter
}
//Controller
#GetMapping(value = "getstdata")
public String getStData(#RequestParam(value="cid") String cid) {
Student student = new Student();
student.setSubjectMark(new SubjectMark());
student.getSubjectMark().setCId(cid);//cid value dynamic
// some other code
return "";
}
2nd part of question:
Now, one of the reason null exception happens when you try to call a method(either setter or getter) from a null object.
you need to write a get set method in your class I guess...
try writing something like
private String cid;
public String Cid { get => cid; set => cid = value; }

JPA AttributeConverter search predicate in specification

I am trying to have a class that has a certain list of objects (specified by another class) persisted in the database as a string (use JPA Converter - all good).
And then I want to use Specification to search inside that string.
What is the best way to create the predicates? I don't seem to understand the connection bettween the AttributeConverter and the Expression in the Specification.
The parent class:
#Entity #Table
public class A {
#Column #Id #GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column
private String name;
#Enumerated(EnumType.STRING)
private SomeType type;
#Column(length=1000) #Convert(converter = BConverter.class)
private List<B> bList;
private Integer no;
}
The listed object class:
public class B{
private String type;
private Integer quantity;
}
The converter:
#Converter
public class BConverter implements AttributeConverter<List<B>, String> {
private static final String SEPARATOR = ":";
private static final String LIST_SEPARATOR = ";";
#Override public String convertToDatabaseColumn(List<B> bList) {
return bList.stream().map(e->convertToString(e)).collect(Collectors.joining(LIST_SEPARATOR));
}
#Override public List<B> convertToEntityAttribute(String str) {
if(str==null || str.isEmpty() ) return null;
return Arrays.stream(str.split(LIST_SEPARATOR)).map(e->convertFromString(e)).collect(Collectors.toList());
}
private String convertToString(B b){
if(entity==null) return null;
return b.getType().toString() +SEPARATOR+ b.getQuantity().toString();
}
private B convertFromString(String subStr){
if(subStr==null || subStr.isEmpty() ) return null;
String[] pair = subStr.split(SEPARATOR);
return new B(pair[0],Integer.valueOf(pair[1]));
}
}
In the database should look something like:
Table A:
id: 1;
name: "Some Name";
type: "THISTYPE";
blist: "TYPE1:11;TYPE2:22";
no: 0;
id: 2;
name: "Other Name";
type: "THISTYPE";
blist: "TYPE1:45;TYPE2:56";
no: 12;
I would then like to create Specifications to search over this table for the attributes inside the bList.
For example, search by an entity that contains a B object where type=TYPE1 and a quantity>=30.
public static Specification<A> customSpecification(String type, Integer value) {
return (root, query, builder) -> ///?????????
}
Is there a way to use such specifications where the DB attribute is a String but JAVA only sees the objects?

multiple language support data from db

My application has entities with nameEn and nameDe for english and german. But only english being used now. Since there are so many entities available, I wanted to have a generic class which can return the selected language entries,but for multiple entries my approach didn't work.
#Entity
#Table(name="employee")
public class Employee implements java.io.Serializable {
// Fields
private Integer id;
private String nameEn;
private String nameDe;
//Getter, Setter Methods
}
#Entity
#Table(name="address")
public class Address implements
java.io.Serializable {
private String descriptionEn;
private String descriptionDe;
}
public interface ILabelText {
String getNameEn();
String getNameDe();
String getDescriptionEn();
String getDescriptionDe();
}
public abstract class LabelText implements ILabelText, Serializable {
private static final long serialVersionUID = 1L;
protected String descriptionEn;
protected String descriptionDe;
private Logger log = Logger.getLogger(LabelText.class);
String language = FacesContext.getCurrentInstance().getViewRoot().getLocale().getLanguage();
public String getDescription() {
log.info("Language Selected is " + language);
if (language.equals("De")) {
return getDescriptionDe();
} else {
return getDescriptionEn();
}
}
public String getName() {
log.info("Language Selected is " + language);
if (language.equals("De")) {
return getNameDe();
} else {
return getNameEn();
}
}
}
//In Xhtml, based on selected locale, display value accordingly
<h:outputText value="#{emp.getName()}" />
<h:outputText value="#{add.getDescription()}" />
You can create an entity Lang like this
#Entity
public class Lang implements Serializable
{
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
#NotNull
private String key;
#NotNull
private String translation;
}
and use it in your Address like this
#OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
#MapKey(name = "key")
protected Map<String, Lang> name;
Then you are able to access the correct language in JSF:
<h:outputText value="#{emp.name[userLocale].translation}" />
The expression userLocale should be resolved to your language key (en, de, ...) or can be hardcoded e.g. #{emp.name['en'].translation}.
Is more easy you create a table with translations:
e.g:
People -> All of your persons
PersonTranslations
People | id
PersonTranslations | locale; person_id;
then on your Person class you set the language for all attributes on predicate
Person.description (this will search on PersonTranslation using a person_id key, and a locale)
some like that PersonTranslation.find(1, 'en');

Categories

Resources