GWT RPC match data for CellTable - java

I have a GWT 2.4 project using a CellTable.
It has columns like this (actually more):
LastName --- FirstName --- Departments
Smith Tom Research, Management
The names I get from a "User" object which is created on the server from my Database.
The DB looks like this:
users:
userID
firstName
lastName
departments:
departmentID
departmentName
user_in_department:
userID
departmentID
So what is the best way to get my departments show up in the table?
At the moment I fetch the User-list and the Department-list from the server using a RPC.
I thought about a 3rd RPC to get me the user-department relation and then match the names to the users on the client. What would be a good way to match that btw?
But even if I had the departments matched to my users, how would I add that info to the table?
For the names I can just do that:
TextColumn<User> firstNameColumn = new TextColumn<User>() {
#Override
public String getValue(User object) {
return object.getFirstName();
}
};
But as the departments aren't stored in the "User" object, I have no idea how to get them in the correct column and row.
I hope I've explained my issue good enough for you to understand :)

Assuming that your User object has a list of departments like so:
public ArrayList<Department> getDepartments() {
// ...
}
You can create a column to list the departments like so:
TextColumn<User> departmentsColumn = new TextColumn<User>() {
#Override
public String getValue(User object) {
StringBuilder departments = new StringBuilder();
for(int i=0; i < object.getDepartments().size(); i++) {
if (i>0) {
departments.append(",");
}
departments.append(object.getDepartments().get(i).getDepartmentName());
}
return departments.toString();
}
};

In addition to the first answer: since a CellTable is parameterized to display a list of objects of a given type in its rows that object should include the user name as well as a list of departments. You'll have to somehow make that data available through the User object, or create a new one (e.g. UserDepartmentDTO) as the elements in the underlying model.

Related

Insert Element into multiple classes of Array in Java

I have these class on my package:
1. Class Goods with attributes (name, price, id) //Goods id is unique, but the name can be the same
2. Class Storage with attributes (Goods gArray[3])
3. Class Store with attributes (name, ArrayList<Storage>) //Store name is unique
4. Class StoreSystem with attributes (ArrayList<Store>)
I want to insert Goods into Storage which belong to certain Store. I already succeed in inserting the Store to ArrayList, but haven't found the way to insert the Goods.
Here's the code for adding the store:
public String addStore(String storeName) {
String output = "";
if(storeCheck(storeName)) { //storeCheck used to check whether the store name exist/not.
output = "store already exist!";
}
else {
Store s1 = new Store();
Storage st1 = new Storage();
s1.setStoreName(storeName);
s1.setStorageList(null);
st1.setGArray(null);
listOfStore.add(s1);
listOfStorage.add(st1);
output = "Store added";
}
return output;
}
You could create a method in the Storage class that:
either takes an index of the array and Goods as arguments and places the Goods in the array at that index (if you're interested in full control of where everything goes)
or just Goods as argument and decides where to put them internally (if you do not care which index in the array the goods go to)
Does that make sense?
I believe is just this, using list as intermediate:
public void addGoods(Goods g) {
List<Goods> storageList = Arrays.asList(this.getGoods());
storageList.add(g);
this.setGoods(storageList.toArray());
}
get and set as usual, and you will need to control the size.
Make a POJO called Storage with the field Goods gArray[3]. Then have a method to add Storage in Store class (it should be as simple as using storeArrayList.add(new Storage()); and pass 3 parameters of type Goods to it). And there you go. You have a Storage and Goods in Storage.
Now properly looking up for a particular Storage in a Store without assigning an index to a particular Storage will be a bit of a bother. Ideally, every Storage object should have an id field.
The code will look something like:
The Store add method:
<return-type> addToStore(Goods[] goods) {
storageArray.add(new Storage(goods));
}
And then the Storage class will look something like:
class Storage {
private final Goods gArray[3];
public Storage(final Goods gArray) {
this.gArray = gArray;
}
// getters
}

What DAO method I should use?

I have two comboboxes connected to a two DatabaseTables in ORMLite. For exammple first combobox shows brands (from brands_table) and second shows models (from models_table). Models_table has also foreignField with brandId. When I'm saving a new record, I must choose brand first then model.
For initializaton and set data in both of comboboxes I use queryForAll method from DAO.
My question is which method I could use for filtering data in second combobox when I already choose something from first. I was thinking about queryForEq and queryForMatching.
For now normal initialize is:
public void initializeModelsList() throws ApplicationException {
CarModelDao carModelDao = new CarModelDao(DBManager.getConnectionSource());
List<CarModel> listOfModels = carModelDao.queryForAll(CarModel.class);
modelsList.clear();
// loop
listOfModels.forEach((c) -> {
// create new object ModelsFX model
ModelsFX modelsFX = ConverterModels.convertToModelFX(c);
this.modelsList.add(modelsFX);
And what I'm thinking about is:
public void initializeFilteredModelsList() throws ApplicationException {
CarBrandDao carBrandDao=new CarBrandDao(DBManager.getConnectionSource());
CarBrand tempCarBrand = carBrandDao.findById(CarBrand.class, this.getModelsFxObjectProperty().getBrandsFXObjectProperty().getId());
//it returns int with ID
CarModelDao carModelDao = new CarModelDao(DBManager.getConnectionSource());
List<CarModel> listOfFilteredModels = carModelDao.//searching for same ID in foreignField(brand_ID) in models_table
listOfFilteredModels.forEach((c) -> {
// create new object ModelsFX model
ModelsFX modelsFX = ConverterModels.convertToModelFX(c);
this.modelsList.add(modelsFX);
});
My question is which method I could use for filtering data in second combobox when I already choose something from first.
If I understand, this is textbook example of foreign objects that is covered very well by the documentation for ORMLite. In the examples from the docs they have Account and Order which in your example would be CarBrand and CarModel.
To quote from the docs:
You can query for foreign fields in a couple of different ways. The following examples show code which queries for all orders that match a certain account field. Since the id field is the name field, you can query by the name field of the account:
// query for all orders that match a certain account
List<Order> results = orderDao.queryBuilder().
where().eq("account_id", account.getName()).query();
Or you can just let ORMLite extract the id field from the account itself. This will perform an equivalent query to the above:
// ORMLite will extract and use the id field internally
List<Order> results = orderDao.queryBuilder().where().eq("account_id", account).query();

How to calculate the outcome of difference between two fields from hibernate and show it on a jsp?

I am making a simple CRUD app, using spring mvc, hibernate and mySQL.
I have a single table in mySQL:
CREATE TABLE `product` (
`id` INT NOT NULL AUTO_INCREMENT,
`product_name` VARCHAR(45) DEFAULT NULL,
`quantity_needed` INT DEFAULT NULL,
`status` INT DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
I have the basics fixes - listing all of the elements on a JSP, adding a new element, updating and deleting.
I want to also show a separate list with just the products, where the status value < quantity_needed with the difference being shown. I created the code to show just the list(without anything else). Below is a part of my productDAOImpl:
#Transactional
#Override
public List<Product> buyList() {
// get the current hibernate session
Session currentSession = sessionFactory.getCurrentSession();
// query the database to find the requested items
Query<Product> theQuery = currentSession.createQuery("from Product p where p.status<p.quantityNeeded");
// get the result list
List<Product> buyList = theQuery.getResultList();
return buyList;
}
and a the controller:
#GetMapping("/buy")
public String buyList(Model theModel) {
// get the requested list of items to be bought
List<Product> theProduct = productDAO.buyList();
// add them to the page
theModel.addAttribute("products", theProduct);
return "buy-list";
}
part of my JSP:
<c:forEach var="tempProduct" items="${products}">
<tr>
<td>${tempProduct.productName}</td>
<td>{tempProduct.difference}</td>
</tr>
In my product entity I created a new field difference
// field for quantityNeeded-status value
#Transient
private int difference;
public int getDifference(Integer quantityNeeded,Integer status) {
difference=quantityNeeded-status;
return difference;
}
As mentioned above, the list I am showing should also have a new parameter, which will be calculated(as a difference of 2 ints from the database).This value will be shown on the page.
How can I do this?
Although it seems a good and straightforward approach, you should never propagate the domain model object outside the business layer, for instance by using entities in the front end.
What you should do, is to create a service layer, with its own dto, where you would put all the information you need to pass to the front end.
So, if your frontend layer needs specific information from the backend, you will create a ProductDTO file with only the fields you need, for instance the productName and the priceDifference.
The service layer will retrieve the information from the DAO, and then translate it into the DTO, to decouple the responsibilities between the datasource and the presentation.
This way, if you change the logic of the calculation of the priceDifference, you just replace the business logic, while the presentation layer will continue working.
I would change:
List<Product> theProduct = productDAO.buyList();
to
List<ProductDTO> theProduct = productService.buyList();
The ProductDTO is a simple POJO with the fields you need and the service would have something like:
public List<ProductDTO> buyList() {
List<Product> myProducts = productDAO.buyList();
//convert the myProduct list to a list of ProductDTO
//calculate the priceDifference
//return the list od DTOs
return dtoList;
}
Quick dirty way -- create the correct getter
public int getDifference() {
return quantityNeeded-status;
}
Proper way is #senape's mentioned above.

Multiple DAOs with dependencies (foreign key)

I am creating an application with database access. I do not use JPA nor JooQ or other frameworks for reasons (and do not want to. Also this is not important for my question). So I use JDBC and write plain sql.
My model looks like this:
public class Contact{
AddressBook addressBok;
String name;
...
}
I now created 2 DAOs, one for Contact and AddressBook. My Contact table has a foreign key to the AddressBook table (address_book_id).
I have a Service Class (e.g. ContactService) which would read each object using the corrsponding DAO and combine it to one Contact.
The Problem now is: I have the address_book_id in the ResultSet in the ContactDAO. How do I pass it over to the service class which then reads the correspondig AddressBook using the AddressBookDAO? As the model is shared, it is not a good solution to put a String addressBookId to Contact as clients using this model may do not know anything about the database.
I know these questions, but there is no answer on how to do it:
Using DAOs with composite Objects
Can a DAO call DAO?
The best practice is to use POJO domain object per each table where you can save your relationship fields like address_book_id. So you will have tree independent classes Contact, Address, AddressBook and independent DAO ContractDAO, AddressDAO, AddressBookDAO. Your ContactService will manipulate with these 6 objects to load, save, modify related data.
you can use the decorator pattern to wrap the entity(model class) that you want to add a foreign key to it, like this:
how to use:
for example: save(insert into db) a contact (here where I found the problem last time, so i fixed it by this solution)--> problem:how to insert a contact without knowing the fk address_book_id, in the args of save
public class ContactDAO extends DAO<Contact>{
// ....
#Override
public int save(IEntity contact){
ForeignKeyWrapper ctFk = (ForeignKeyWrapper)contact;
int address_book_id = ctFk.getFK();
Contact ct = (Contact)ctFk.getEntity();
String name = ct.getName();
// retrieve other fields of contact here
//use some sql to insert the contact in the db, now you have also the fk
String insertQuery = "INSERT INTO CONTACT(name,..other fields of contact.. , address_book_id) VALUES("+
name + "," +
/*other fields*/
address_book_id + ")";
//execute it here and fetch the id of the inserted row
}
// ....
}
public class clientClass{
//....
public static void main(String[] args) {
IEntity contact = new Contact(/* init fields*/);
IEntity addressBook = new AddressBook(/* init fields*/);
ForeignKeyWrapper ctFKW = new ForeignKeyWrapper(contact);
//link contact to addressBook (e.g: when creating a contact to insert it into the db)
ctFKW.setFK(addressBook.getId());
ContactDAO ctDAO = new ContactDAO(/*connection*/);
ctDAO.save(ctFKW);
}
//....
}
you can add a builder class to build your contact objects and link their foreign keys to addressBook objects Ids, to encapsulate the building logic, and simplify the process

Objectify app engine - querying embedded entities using a list of values

I am using objectify-appengine framework for querying. Here is my simplified problem: Consider these 2 classes:-
public class Customer {
#Id private String email;
#Embedded private Account Account = new Account(); // note embedded annotation
}
and
public class Account {
private String number; //example: 1234
}
The following query works & gives me 1 customer:
Objectify ofy = ObjectifyService.begin();
ofy.query(Customer.class).filter("account.number = ", "1234");
Question:
However, if have a List of values (account numbers). Is there a way to fetch them in 1 query? I tried passing a list of account numbers like this:
ofy.query(Customer.class).filter("account.number = ", myAccountNumberList);
But if fails saying:
java.lang.IllegalArgumentException: A collection of values is not allowed.
Thoughts?
filter("account.number IN", theList)
Note that IN just causes the GAE SDK to issue multiple queries for you, merging the results:
The IN operator also performs multiple queries, one for each item in the specified list, with all other filters the same and the IN filter replaced with an EQUAL filter. The results are merged, in the order of the items in the list. If a query has more than one IN filter, it is performed as multiple queries, one for each possible combination of values in the IN lists.
From https://developers.google.com/appengine/docs/java/datastore/queries

Categories

Resources