How to get a specific attribute from an object list? - java

I've an array keeping a list of Group objects. I want to set this list to the DropDownChoice component. However I want to show the end user only the name attribute of Group objects, and then get the selected values' id attribute to add database. What to do?
private List<Group> groupTypes;
DatabaseApp db = new DatabaseApp();
groupTypes = db.getGroups();
groupDropDownChoice = new DropDownChoice("type", groupTypes);
...
...
addUserForm.add(new Button("submit"){
#Override
public void onSubmit(){
Group group = (Group) groupDropDownChoice.getModelObject();
...
...
db.addUser(group.getId(), den, name, login, email, password1);
DatabaseApp.java
public List<Group> getGroups() throws SQLException{
List<Group> groups = new ArrayList<Group>();
try {
String query = "SELECT * FROM [GROUP]";
Statement statement = db.createStatement();
ResultSet result = statement.executeQuery(query);
while(result.next()){
int id = result.getInt("ID");
String name = result.getString("NAME");
groups.add(new Group(id, name));
}
result.close();
} catch (SQLException ex) {
throw new SQLException(ex.getMessage());
}
return groups;
}

DropDownChoice has another constructor accepting an additional parameter of an IChoiceRenderer that allows control of what's displayed and what's sent back with the form.
See this example.
In your code, an implementation could look approximately like
private List<Group> groupTypes;
DatabaseApp db = new DatabaseApp();
groupTypes = db.getGroups();
groupDropDownChoice = new DropDownChoice("type", groupTypes, new IChoiceRenderer(){
#Override
public Object getDisplayValue(Object object) {
return ((Group) object).getName();
}
#Override
public String getIdValue(Object object, int index) {
return Integer.toString(index);
}
});
...
...
addUserForm.add(new Button("submit"){
#Override
public void onSubmit(){
Group group = (Group) groupDropDownChoice.getModelObject();
...
...
db.addUser(group.getId(), den, name, login, email, password1);

You're just creating the DropDownChoice directly from the list of groups. It seems to me that what you really want is a model for the list of groups; see the IModel documentation. Then you can create a custom model that returns only the name of a group instead of the whole Group object.

Related

JUnit expected: but was: Error - Understanding JUnit

I am new to JUnit and testing and am seriously at my wits end with this error:
expected:<null> but was: expected:<null> but was:<Order ID: 1, Customer ID: 1, Customer Name: jordan harrison, Item ID: 1, Item Name: Call of Duty, Quantity: 0, Total Cost: 0.0>
I have no idea why the below test does not work whatsoever. I have looked at other similar questions but they don't help my understanding of the tests at all and left me at a complete loss for how to fix this.
Here's the test:
public class OrderDAOTest {
private final OrderDAO DAO = new OrderDAO();
#Before
public void setup() {
DBUtils.connect();
DBUtils.getInstance().init("src/test/resources/sql-schema.sql", "src/test/resources/sql-data.sql");
}
#Test
public void testRead() {
Long oId = 1L;
Long iId = 1L;
Long cId = 1L;
String iName = "Call of Duty";
double iCost = 25.99;
Item item = new Item(iId, iName, iCost);
Customer customer = new Customer(cId);
CustomerDAO custDao = new CustomerDAO();
customer = custDao.read(customer.getCustomerId());
Order order = new Order();
order.setOrderId(1L);
order.setItem(item);
order.setCustomer(customer);
System.out.println(order);
assertEquals(DAO.read(order.getOrderId()), order);
}
This is the read() method with the orderItemsFromResultSet() method that it returns in the OrderDAO Class:
public Order orderItemsFromResultSet(ResultSet rs) throws SQLException {
Long orderId = rs.getLong("fk_order_id");
Long itemId = rs.getLong("item_id");
String itemName = rs.getString("item_name");
double itemCost = rs.getDouble("item_cost");
Item item = new Item(itemId, itemName, itemCost);
Order order = new Order(item, orderId);
return order;
}
#Override
public Order read(Long id) {
try (Connection connection = DBUtils.getInstance().getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT * FROM order_items LEFT OUTER JOIN items ON items.item_id = order_items.fk_item_id WHERE fk_order_id = ?");) {
statement.setLong(1, id);
try (ResultSet resultSet = statement.executeQuery();) {
resultSet.next();
return orderItemsFromResultSet(resultSet);
}
} catch (Exception e) {
LOGGER.debug(e);
LOGGER.error(e.getMessage());
}
return null;
}
I just don't understand it and need help with understanding testing altogether.
You are catching all exceptions and then just returning null. There are two possible places I would debug further.
Check if the Connection is working fine.
Check if the query execution works fine too. Remove the semicolon at the end of the query and it may work.
The logs may help you here.

How would I unit test jdbcTemplate.query that have overrides?

I have a class that uses multiple get methods the returns
public int getCurrNum(String Name) {
// query clearances table to return an int that represents the clearance level
String sql = "SELECT number FROM clearances WHERE '" + Name + "' = name;";
//String.format("SELECT number FROM clearances WHERE '%s' = name;",clearanceName);
return jdbcTemplate.queryForObject(sql, Integer.class);
}
which I understand I can use Mockito with a statement like Mockito.when(jdbcTemplate.queryForObject(Mockito.anyString(), Mockito.eq(Integer.class))).thenReturn(1);
But that is not really testing values that are being passed in because I am just telling it to return a value I want. I want to make sure all these methods return what the parameters are specially passing in. We have a user token with user details being sent in. We also have more JdbcTemplates such as
public List<String> getCurr(String currCountry) {
// query alliances table to return a list of alliance tags that countain the
// user's country tag
String sql = "SELECT * FROM user WHERE '" + currCountry + "' = ANY(access_tags) ;";
return jdbcTemplate.query(sql, new RowMapper<String>() {
#Override
public String mapRow(ResultSet rs, int rownumber) throws SQLException {
return rs.getString(1);
}
});
Then the last methods combines everything and has this return statement that uses all these setters from another class.
// return list of appropriately filtered missions
return jdbcTemplate.query(sql, new RowMapper<Mission>() {
#Override
public OtherClass mapRow(ResultSet rs, int rownumber) throws SQLException {
OtherClass m = new OtherClass();
m.setNumber(rs.getInt(1));
m.setName(rs.getString(2));
m.setLastCheckinDate(rs.getString(3));
m.setLocation(rs.getString(4));
m.setCurrLocation(rs.getString(5));
m.setFinalLocation(rs.getString(6));
m.setTags(rs.getString(7));
return m;
}
});
}
But I am not sure how to test these statements. Without using the Mockito.when commands, they always turn out null. We have this information in a database .xml file for the column and rows so it knows what information to grab to fill in the lists. Do I need to mock a mock db or something to test this?

put in hashmap using two lists and database

I have two classes, User and Customer, using hibernate, I have mapped these tables, now I want to retrieve the data from the database, where I can put the values in hashmap such that for each user, if a particular customer exists in the mapping table, then the key of map is set as the customer name, and value to true or false, depending upon the mapping table.
I have retrieved both the lists:
static List<User> listUsers = new ArrayList<User>();
static List<Customer> listCustomers = new ArrayList<Customer>();
List<UserTO> list = new ArrayList<UserTO>();
public static List<Customer> getListOfCustomers() {
HibernateUtil.openSession();
Session session = HibernateUtil.getSession();
Transaction tx = null;
try {
tx = session.getTransaction();
tx.begin();
listCustomers = session.createQuery("from Customer").list();
tx.commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
return listCustomers;
}
(similarly list of users)
in UserTO class, I have:
public class UserTO implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
private String userId;
private Map<String, Boolean> map = new HashMap<String, Boolean>();
(getter and setter)
I tried doing this:
public static void execute() {
getListOfUsers();
getListOfCustomers();
for (User user : listUsers) {
UserTO u = new UserTO();
Map<String, Boolean> map = new HashMap<>();
for (Customer customer : listCustomers) {
if (customer.getCompanyName() == user.getCustomers(customer)) {
map.put(customer.getCompanyName(), true);
} else {
map.put(customer.getCompanyName(), false);
}
}
user.getUserId();
u.setUserId(user.getUserId());
u.setMap(map);
listUsers.add(user);
}
}
which gives me Concurrent Modification Exception
I don't know where I am doing wrong, and what should I do next.
you are adding user to listUsers when you are iterating over this listuser. This results in the given exception.
Use list.add(u);
Reason for ConcurrentModificationException is you are trying to add to the list at the same time when you are iterating like:
for (User user : listUsers) {
....
listUsers.add(user);
One way to solve this would be to create a temporary list and keep adding to that list and after your for loop, use addAll method on listUsers to add all your users that you added in the loop.
Note: Inorder to select the data, you don't need transaction as select wont do any side effect to your table.
What you are trying to do is that you are getting a User object from the list, and then again adding it to the list. It wont work for the following reasons:
You are iterating the list and adding in the same loop which is not allowed and throws ConcurrentModificationException.
Also you are adding in every iteration. Which means that the list will grow with every iteration and your loop will never end. First you should remove the object and then again add it in the same place.
Solution:
public static void execute() {
getListOfUsers();
getListOfCustomers();
for (int i=0;i<listUsers.size();i++) {
User user = listUsers.remove(i);
UserTO u = new UserTO();
Map<String, Boolean> map = new HashMap<>();
for (Customer customer : listCustomers) {
if (customer.getCompanyName() == user.getCustomers(customer)) {
map.put(customer.getCompanyName(), true);
} else {
map.put(customer.getCompanyName(), false);
}
}
user.getUserId();
u.setUserId(user.getUserId());
u.setMap(map);
listUsers.add(i,user);
}
}
P.S. - But still I don't get that why there is a need to add an object which already exists in the list without any change.
You are getting concurrent modification exception as HashMap is not thread safe. Use concurrentHashMap instead. Thanks hope it helps.

How to save id's other than keyword in SuggestBOX?

I am using a simply city SuggestBox where I am getting list of cities from the database and putting them in GWT suggestBox oracle.
After that user can select his city from the suggestBox suggestions and user saves his record. For example, he will select "London" from the suggestbox list.
Now when user saves his record, I will not save "London" in the database for that user, instead I want to save "3" (london ID) in database.
For this what I am doing is like this:
public MultiWordSuggestOracle createCitiesOracle(ArrayList<City> cities){
for(int i=0; i<cities.size(); i++){
oracle.add(cities.get(i).getCity()+","+cities.get(i).getCityId());
}
return oracle;
}
Now, I have the city and cityID both displaying in suggestBox and then can save from there 'city' and 'cityId'.
Everything works fine, but it doesn't looks good:
like it dispays as "London,3" and so on in the suggestBox suggestions..
I don't want to show this 3, how and where can I save this Id(3) for future use?
You can also create your own typed Suggestion-Box. You need to implement "Suggestion" and extend "SuggestOracle".
Super simple version may look:
// CityOracle
public class CityOracle extends SuggestOracle {
Collection<CitySuggestion> collection;
public CityOracle(Collection<CitySuggestion> collection) {
this.collection = collection;
}
#Override
public void requestSuggestions(Request request, Callback callback) {
final Response response = new Response();
response.setSuggestions(collection);
callback.onSuggestionsReady(request, response);
}
}
//CitySuggestion
public class CitySuggestion implements Suggestion, Serializable, IsSerializable {
City value;
public CitySuggestion(City value) {
this.value = value;
}
#Override
public String getDisplayString() {
return value.getName();
}
#Override
public String getReplacementString() {
return value.getName();
}
public City getCity() {
return value;
}
}
// Usage in your code:
// list of cities - you may take it from the server
List<City> cities = new ArrayList<City>();
cities.add(new City(1l, "London"));
cities.add(new City(2l, "Berlin"));
cities.add(new City(3l, "Cracow"));
// revert cities into city-suggestions
Collection<CitySuggestion> citySuggestions = new ArrayList<CitySuggestion>();
for (City city : cities) {
citySuggestions.add(new CitySuggestion(city));
}
//initialize city-oracle
CityOracle oracle = new CityOracle(citySuggestions);
// create suggestbox providing city-oracle
SuggestBox citySuggest = new SuggestBox(oracle);
// now when selecting an element from the list, the CitySuggest object will be returned. This object contains not only a string value but also represents selected city
citySuggest.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
#Override
public void onSelection(SelectionEvent<Suggestion> event) {
Suggestion selectedItem = event.getSelectedItem();
//cast returned suggestion
CitySuggestion selectedCitySuggestion = (CitySuggestion) selectedItem;
City city = selectedCitySuggestion.getCity();
Long id = city.getId();
}
});
Keep the reference from city name to id in a Map<String, Integer> and then look the ID up there before you save it.

Java Combobox, Managing 2 fields from database

I want to get a result set with 2 fields from my DB.
rs=Con.sqlQueryTable("Select id_prov, name_prov from prov");
And then I want to show the field called "name_prov" in the comboBox (As the item). But I also want to have my "id_prov" which is the ID (PRIMARY KEY) as the value for this item. This serves for the purpose of relating the name (of the providers in this case) with its ID just by using the combobox.
This is the code of the JComboBox event FocusGained that Im currently using.
try {
//CBProv is the Combobox
CBProv.removeAllItems();
rs=Con.sqlQueryTable("Select id_prov, name_prov from prov");
while(rs.next())
{
CBProvedores.addItem(rs.getString("name_prov"));
//Here should be the Value related to the item I am creating
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Error" + e );
}
Is there anyway I can accomplish this?
First create a POJO, which will hold both your name and id.
public class ComboItem {
private String id;
private String name;
public ComboItem(String id, String name) {
this.id = id;
this.name = name;
}
// Add the getter and setter as you want.
// This will be used internally by JComboBox as the label to be displayed.
#Override
public String toString() {
return name;
}
}
Then use this POJO objects to be put into your JComboBox.
try {
//CBProv is the Combobox
CBProv.removeAllItems();
rs=Con.sqlQueryTable("Select id_prov, name_prov from prov");
while(rs.next())
{
String id = rs.getString("id_prov"); // Get the Id
String name = rs.getString("name_prov"); // Get the Name
ComboItem comboItem = new ComboItem(id, name); // Create a new ComboItem
CBProv.addItem(comboItem); // Put it into the ComboBox
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Error" + e );
}
And then finally to get the value selected, you can do this:-
CBProv.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ComboItem comboItem = (ComboItem) CBProv.getSelectedItem();
// comboItem.getId(), comboItem.getName() - Use as you wish.
}
});
Hi there i am Also still a newbie to java and javafx. This is what i did in javafx and it worked for me Hope you can work around it in java.
private void fillProviders()
{
List<String> providerList = new ArrayList<String>();
try
{
String Sql = "select * from prov ";
pat= conn.prepareStatement(Sql);
rs=pat.executeQuery();
while (rs.next())
{
providerList.add(rs.getString("id_prov")+" "+ rs.getString("name_prov"));
}
ObservableList<String> provider = FXCollections.observableArrayList(providerList);
bankName.setItems(provider);
}
catch( Exception e)
{
JOptionPane.showMessageDialog(null, e);
}
}
Hope it works for you. Note that my my combobox Name is bankName

Categories

Resources