How to populate a ChoiceBox with items from a database - java

I'm trying to populate a ChoiceBox with items(Countries) from a H2 database via Hibernate, but the ChoiceBox only gets populated with some strange items that don't make sense, instead of the actual countries names; something like this:
project.Forms.AddNew.DB.ItemsPOJO#5aa434
How can I get the actual countries names from the database instead of values like the above?
The classes look as follows:
The POJO class:
#Entity(name = "InitialDBItems")
public class InitialDBItemsPOJO implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int countriesListID;
private String countriesList;
public String getCountriesList() {
return countriesList;
}
public void setCountriesList(String countriesList) {
this.countriesList = countriesList;
}
public int getCountriesListID() {
return countriesListID;
}
public void setCountriesListID(int countriesListID) {
this.countriesListID = countriesListID;
}
}
The countries array that gets persisted into the database:
public class InitialDBItems {
static InitialDBItemsPOJO initialDBItemsPOJO = new InitialDBItemsPOJO();
public static void persistCountries() {
String[] countriesList = {
"Afghanistan",
"Albania",
"Algeria",
// More countries
};
for (String c : countriesList) {
initialDBItemsPOJO.setCountriesList(c);
new ManageItems().addItems(initialDBItemsPOJO);
System.out.println(c);
}
}
How I get the countries from the database:
public static ObservableList<InitialDBItemsPOJO> retrieveCountriesList() {
ObservableList<InitialDBItemsPOJO> data;
List countriesListListItems;
String countriesListListItemsQuery = "from InitialDBItems";
data = FXCollections.observableArrayList();
countriesListListItems = new ManageItems().listItems(countriesListListItemsQuery);
for (Iterator iterator = countriesListListItems.iterator(); iterator.hasNext();) {
InitialDBItemsPOJO countriesListListItemsIt = (InitialDBItemsPOJO) iterator.next();
data.add(countriesListListItemsIt);
}
return data;
}
}
Hope you can help. Thank you all in advance.

project.Forms.AddNew.DB.ItemsPOJO#5aa434 is the value of the default toString(); of your entity InitialDBItemsPOJO an easy work around is to override it
#Entity(name = "InitialDBItems")
public class InitialDBItemsPOJO implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int countriesListID;
private String countriesList;
public String getCountriesList() {
return countriesList;
}
public void setCountriesList(String countriesList) {
this.countriesList = countriesList;
}
public int getCountriesListID() {
return countriesListID;
}
public void setCountriesListID(int countriesListID) {
this.countriesListID = countriesListID;
}
public String toString(){
return countriesList;
}
}
or
public static ObservableList retrieveCountriesList() {
ObservableList<InitialDBItemsPOJO> data;
List countriesListListItems;
String countriesListListItemsQuery = "from InitialDBItems";
data = FXCollections.observableArrayList();
countriesListListItems = new ManageItems().listItems(countriesListListItemsQuery);
for (Iterator iterator = countriesListListItems.iterator(); iterator.hasNext();) {
InitialDBItemsPOJO countriesListListItemsIt = (InitialDBItemsPOJO) iterator.next();
data.add(countriesListListItemsIt.getCountriesList());
}
return data;
}

Related

Room TypeConverter not working

I have an issue with Room not recognizing my converter. Error:
Cannot figure out how to save this field into database. You can consider adding a type converter for it.
I need to store some maps and sets in my database. What am I doing wrong? Does room not like interfaces or generics?
code: (sorry for all the fields and class name, they are a mixture of English and Czech to not have same names as some java classes):
Converter (only part)
public class MyConverter {
/**
* makes a string like 1;2;3;5;4;8;1;6;8;4 from a collection of integers.
*/
#TypeConverter
public static #NonNull String toString(#NonNull Collection<Integer> c) {
StringBuilder sb = new StringBuilder();
for (Integer item : c) {
sb.append(item.toString() + ";");
}
sb.delete(sb.length()-1,sb.length()-1);
return sb.toString();
}
/**
* makes a Set<Integer> from string like 1;2;3;4;5;6
* #throws NumberFormatException on incorrect input
*/
#TypeConverter
public static#NonNull Set<Integer> toIntegerSet(#NonNull String s) {
Set<Integer> set = new LinkedHashSet<>();
String[] split = s.split(";");
try {
for (String item : split) {
set.add(Integer.parseInt(item));
}
}catch (NumberFormatException e){
throw new NumberFormatException("Could not make set of integers (like 1;2;3;8;7) from \"" + s +"\"");
}
return set;
}
}
Database:
#Database(entities = {SQLUkol.class,SQLPredmet.class,SQLList.class},version = 1)
#TypeConverters({MyConverter.class})
public abstract class AppDatabase extends RoomDatabase {
public abstract MojeDAO mojeDao();
}
One of the entities (getters, setters and constructors not included):
#Entity(primaryKeys = {"id", "list_id"},
indices = {#Index("list_id")},
foreignKeys = #ForeignKey(entity = SQLList.class, parentColumns = "id",
childColumns = "list_id", onDelete = ForeignKey.CASCADE),
tableName = "ukols")
public class SQLUkol implements Comparable<SQLUkol> {
#ColumnInfo(name = "list_id")
private final int listID;
private final int id;
private String title;
#ColumnInfo(name = "title_changed")
private boolean titleChanged = false;
private String notes;
#ColumnInfo(name = "notes_changed")
private boolean notesChanged = false;
private boolean completed;
#ColumnInfo(name = "completed_changed")
private boolean completedChanged = false;
private LocalDate date;
#ColumnInfo(name = "date_changed")
private boolean dateChanged = false;
#Embedded
private final SQLData data;
}
Room does not like generics much. I had to do this:
#TypeConverter
public static String toString1(Map<String, String> m){
...
}
#TypeConverter
public static String toString2(Map<Integer, String> m){
...
}
#TypeConverter
public static String toString3(Set<Integer> s){
...
}
#TypeConverter
public static String toString4(List<Integer> l){
...
}
not just
#TypeConverter
public static String toString(Map m){
...
}
#TypeConverter
public static String toString(Collection<Integer> c){
...
}

How to filter pojo class and make new pojo class from them

I have one POJO class .ContactPOJO.class
#PrimaryKey(autoGenerate = true)
private int id;
private String contact_id;
private String contact_name;
private String contact_number;
private boolean is_selected;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContact_id() {
return contact_id;
}
public void setContact_id(String contact_id) {
this.contact_id = contact_id;
}
public boolean isIs_selected() {
return is_selected;
}
public void setIs_selected(boolean is_selected) {
this.is_selected = is_selected;
}
public String getContact_name() {
return contact_name;
}
public void setContact_name(String contact_name) {
this.contact_name = contact_name;
}
public String getContact_number() {
return contact_number;
}
public void setContact_number(String contact_number) {
this.contact_number = contact_number;
}
Now I have to make new POJO class but only for that which is_selected boolean value is true in ContactPOJO. I don't know how to do that . Any help would be appreciate.Thanks in advance
EDIT: I have List<ContactPOJO> list_contact . Which contains all contacts from phone . Now some of them will be selected ,some of them will be not . its selected or not will be stored in is_selected variable . now I have to make new list .lets say List<newContactPOJO> . but it will contain only is_selected true value from that old one.
List<ContactPOJO> list_contact;
List<ContactPOJO> list_selected_contact = new ArrayList();
for (ContactPOJO pojo : list_contact){
pojo.setIs_selected(true);
list_selected_contact.add(pojo);
}
==> now you have a new list with all selected object

How to iterate over json data with gson

My json string is:
{
"recordsTotal":1331,
"data":[
{
"part_number":"3DFN64G08VS8695 MS",
"part_type":"NAND Flash",
"id":1154,
"manufacturers":[
"3D-Plus"
]
},
{
"part_number":"3DPM0168-2",
"part_type":"System in a Package (SiP)",
"id":452,
"manufacturers":[
"3D-Plus"
]
},
{
"part_number":"3DSD1G16VS2620 SS",
"part_type":"SDRAM",
"id":269,
"manufacturers":[
"3D-Plus"
]
}
]
}
This code lets me access the two highest level elements:
JsonObject jsonObject = new JsonParser().parse(jsonString).getAsJsonObject();
System.out.println("data : " + jsonObject.get("data"));
System.out.println("recordsTotal : " + jsonObject.get("recordsTotal"));
But what I want to do is iterate over all the objects inside "data" and create a list of part_numbers. How do I do that?
JsonArray is an Iterable<JsonElement>. So you can use for in loop.
JsonObject jsonObject = new JsonParser().parse(jsonString).getAsJsonObject();
final JsonArray data = jsonObject.getAsJsonArray("data");
System.out.println("data : " + data);
System.out.println("recordsTotal : " + jsonObject.get("recordsTotal"));
List<String> list = new ArrayList<String>();
for (JsonElement element : data) {
list.add(((JsonObject) element).get("part_number").getAsString());
}
Suppose class Name for Json Model is Example.
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Example {
#SerializedName("recordsTotal")
private Integer recordsTotal;
#SerializedName("data")
private List<Datum> data = null;
public Integer getRecordsTotal() {
return recordsTotal;
}
public void setRecordsTotal(Integer recordsTotal) {
this.recordsTotal = recordsTotal;
}
public List<Datum> getData() {
return data;
}
public void setData(List<Datum> data) {
this.data = data;
}
}
And suppose List of Data class name is Datum :-
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Datum {
#SerializedName("part_number")
private String partNumber;
#SerializedName("part_type")
private String partType;
#SerializedName("id")
private Integer id;
#SerializedName("manufacturers")
private List<String> manufacturers = null;
public String getPartNumber() {
return partNumber;
}
public void setPartNumber(String partNumber) {
this.partNumber = partNumber;
}
public String getPartType() {
return partType;
}
public void setPartType(String partType) {
this.partType = partType;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<String> getManufacturers() {
return manufacturers;
}
public void setManufacturers(List<String> manufacturers) {
this.manufacturers = manufacturers;
}
}
And then through Gson library we can convert json to java Model :
Example example = new Gson().fromJson(jsonString, new TypeToken<Example>() {}.getType());
Now we can get list of data though example model :-
List<Datum> dataList = example.getData();
From dataList you can traverse and get all info.
If partNmber List we need then we can get in this way :-
List<String> partNumberList = new ArrayList<>();
for (Datum data : dataList) {
partNumberList.add(data.getPartNumber());
}
The given code will not guaranteed to 100% equivalent but it will help you to work.
First you have to create the class for your data objects:
class mydata {
public String part_name;
public String part_type;
public int Id;
public String manufacturers;
}
Your main method should look like
public static void main(String[] args) {
JSONObject obj = new JSONObject();
List<mydata> sList = new ArrayList<mydata>();
mydata obj1 = new mydata();
obj1.setValue("val1");
sList.add(obj1);
mydata obj2 = new mydata();
obj2.setValue("val2");
sList.add(obj2);
obj.put("list", sList);
JSONArray jArray = obj.getJSONArray("list");
for(int ii=0; ii < jArray.length(); ii++)
System.out.println(jArray.getJSONObject(ii).getString("value"));
}
For futher exploration you can use that link:
https://gist.github.com/codebutler/2339666

Spring Data JPA - Get the values of a non-entity column of a custom native query

I am using Spring Boot/MVC.
I have a custom query using JpaRepository:
public interface WorkOrderRepository extends JpaRepository<WorkOrder, Integer> {
#Query(value = "SELECT * FROM (SELECT * FROM workorder) Sub1 INNER JOIN (SELECT wo_number, GROUP_CONCAT(service_type SEPARATOR ', ') AS 'service_types' FROM service_type GROUP BY wo_number) Sub2 ON Sub1.wo_number=Sub2.wo_number WHERE fleet_company_id=?1 AND (order_status='On-Bidding' OR order_status='Draft')", nativeQuery = true)
Collection<WorkOrder> findWorkOrdersByFleet(Long fleetCompanyID);
}
It returns the following table:
http://imgur.com/Ylkc6U0
As you can see it has service_types columns which is a result of Concat, it's not part of the entity class. My problem is how can I get the value of that column. Some said I can use a separate DTO to map the service_types column? Or I can use 'new' keyword? Maybe you have other worked on me. I also tried to make a transient column service_types but it didn't work.
This is my entity class:
#Entity
#Table(name="workorder")
public class WorkOrder {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="wo_number")
private Long woNumber;
#ManyToOne(optional=false, cascade=CascadeType.ALL)
#JoinColumn(name = "vehicle_id")
private Vehicle vehicle;
#ManyToOne(optional=false, cascade=CascadeType.ALL)
#JoinColumn(name = "fleet_company_id")
private FleetCompany fleetCompany;
#Column(name="order_title")
private String orderTitle;
#Column(name="order_date")
private String orderDate;
#Column(name="order_time")
private String orderTime;
#Column(name="order_status")
private String orderStatus;
#Column(name="ref_number")
private String refNumber;
#Column(name="proposals")
private int proposals;
//#Column(name="serviceTypes")
#Transient
private int serviceTypes;
public WorkOrder() {
super();
}
public Long getWoNumber() {
return woNumber;
}
public void setWoNumber(Long woNumber) {
this.woNumber = woNumber;
}
public String getOrderTitle() {
return orderTitle;
}
public void setOrderTitle(String orderTitle) {
this.orderTitle = orderTitle;
}
public String getOrderDate() {
return orderDate;
}
public void setOrderDate(String orderDate) {
this.orderDate = orderDate;
}
public String getOrderTime() {
return orderTime;
}
public void setOrderTime(String orderTime) {
this.orderTime = orderTime;
}
public String getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
public String getRefNumber() {
return refNumber;
}
public void setRefNumber(String refNumber) {
this.refNumber = refNumber;
}
public int getProposals() {
return proposals;
}
public void setProposals(int proposals) {
this.proposals = proposals;
}
public Vehicle getVehicle() {
return vehicle;
}
public void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}
public FleetCompany getFleetCompany() {
return fleetCompany;
}
public void setFleetCompany(FleetCompany fleetCompany) {
this.fleetCompany = fleetCompany;
}
public int getServiceTypes() {
return serviceTypes;
}
public void setServiceTypes(int serviceTypes) {
this.serviceTypes = serviceTypes;
}
}
Some people told me to make a DTO:
public class WorkOrderDTO extends WorkOrder {
private String service_types;
public WorkOrderDTO() {
super();
}
public WorkOrderDTO(String service_types) {
this.service_types = service_types;
}
public String getService_types() {
return service_types;
}
public void setService_types(String service_types) {
this.service_types = service_types;
}
}
and add make the repository replaced from WorkOrder to WorkOrderDTO.
public interface WorkOrderRepository extends JpaRepository<WorkOrderDTO, Integer>
but when I do that I have autowiring problems.
I solved my own problem, finally!!!
I used #SqlResultMapping
SqlResultSetMapping(
name="workorder",
classes={
#ConstructorResult(
targetClass=WorkOrderDTO.class,
columns={
#ColumnResult(name="wo_number", type = Long.class),
#ColumnResult(name="service_types", type = String.class),
#ColumnResult(name="order_title", type = String.class)
}
)
}
)
And I created a new POJO that is not an entity named WorkOrderDTO.
#PersistenceContext
private EntityManager em;
#Override
public Collection<WorkOrderDTO> getWork() {
Query query = em.createNativeQuery(
"SELECT Sub1.wo_number, Sub2.service_types, Sub1.order_title FROM (SELECT * FROM workorder) Sub1 INNER JOIN (SELECT wo_number, GROUP_CONCAT(service_type SEPARATOR ', ') AS 'service_types' FROM service_type GROUP BY wo_number) Sub2 ON Sub1.wo_number=Sub2.wo_number WHERE fleet_company_id=4 AND (order_status='On-Bidding' OR order_status='Draft')", "workorder");
#SuppressWarnings("unchecked")
Collection<WorkOrderDTO> dto = query.getResultList();
Iterable<WorkOrderDTO> itr = dto;
return (Collection<WorkOrderDTO>)itr;
}
At last, the users who hated me for posting the same problem won't be annoyed anymore.

DynamoDB mapping List of Enum

Mapping an enum class in to DynamoDB object is really simple by using Custom Marshall. But how to map a List of Enum?
Enum class
public enum Transport {
SMS,EMAIL,ALL;
}
DynamoDB mapper
public class Campaign{
private List<Transport> transport;
#DynamoDBAttribute(attributeName = "transport")
public List<Transport> getTransport() {
return transport;
}
public void setTransport(List<Transport> transport) {
this.transport = transport;
}
}
DynamoDBMarshaller is deprecated.
Use DynamoDBTypeConverter instead.
Example:
Enum class
public static enum ValidationFailure {
FRAUD, GENERAL_ERROR
}
DynamoDBTable class
#DynamoDBTable(tableName = "receipt")
public class Receipt {
private Long id;
private List<ValidationFailure> validation;
#DynamoDBHashKey(attributeName = "id")
public Long getId() {
return id;
}
#DynamoDBTypeConverted(converter = ValidationConverter.class)
public List<ValidationFailure> getValidation() {
return validation;
}
public void setId(Long id) {
this.id = id;
}
public void setValidation(List<ValidationFailure> validation) {
this.validation = validation;
}
}
Convertor:
public class ValidationConverter implements DynamoDBTypeConverter<List<String>, List<ValidationFailure>> {
#Override
public List<String> convert(List<ValidationFailure> object) {
List<String> result = new ArrayList<String>();
if (object != null) {
object.stream().forEach(e -> result.add(e.name()));
}
return result;
}
#Override
public List<ValidationFailure> unconvert(List<String> object) {
List<ValidationFailure> result = new ArrayList<ValidationFailure>();
if (object != null) {
object.stream().forEach(e -> result.add(ValidationFailure.valueOf(e)));
}
return result;
}
}
It's working for me, I have used the Set
#DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.SS)
var roles: MutableSet<Employee.Role>? = null
I think the same approach would work for List with DynamoDBAttributeType.L
I found the answer myself. I create a custom marshall like below.
public class TransportMarshaller implements DynamoDBMarshaller<List<Transport>> {
#Override
public String marshall(List<Transport> transports) {
List<String>transportMap=new ArrayList<>();
for(Transport transport:transports){
transportMap.add(transport.name());
}
return transportMap.toString().replaceAll("\\[|\\]", "");//Save as comma separate value for the purpose of easiness to unmarshall
}
#Override
public List<Transport> unmarshall(Class<List<Transport>> aClass, String s) {
List<String>map= Arrays.asList(s.split("\\s*,\\s*")); //split from comma and parse to List
List<Transport>transports=new ArrayList<>();
for (String st:map){
transports.add(Transport.valueOf(st));
}
return transports;
}
}

Categories