I have two types of java beans that can be associated with a User java bean:
PrivateTeacher and CompanyTeacher.
These two java beans are similar, only for one of their properties, say "subject", the PrivateTeacher will always have one while the CompanyTeacher can have several.
Would it make more sense to have a single java bean for both of these types of users where the "subject" field will be an ArrayList and the PrivateTeacher will only fill one element of the ArrayList whereas the CompanyTeacher can fill several?
Or should I have two separate java beans: one with an int field and another with an ArrayList<Integer> field (for the subject id's field)?
On one hand, the latter way is more precise. On the other, I don't want to limit methods that I have such as say, "findTeachers", which could satisfy both types of java beans (pass a parameter saying the bean type: "company" or "private" and then the User bean will be different but the Teacher bean will be the same).
Any suggestions or explanations?
Thank you
It depends...
If you want to treat both PrivateTeacher and CompanyTeacher in the same manner (polymorphicaly) then List<Integer> (not ArrayList) would be a better approach. But if this is not the case then - use the more precise way to describe them.
You can have a PrivateTeacher that supports both methods:
public String getSubject(int index) {
return index < subjects.size() ? subjects.get(index) : subjects.get(subjects.size()-1);
}
public String getSubject() {
return getSubject(0);
}
Related
I have implemented some REST API with springMVC+Jackson+hibernate.
All I needed to do is retrieve objects from database, return it as a list, the conversion to JSON is implicit.
But there is one problem. If I want to add some more information to those object before return/response. For example I am returning a list of "store" object, but I want to add a name of the person who is attending right now.
JAVA does not have dynamic type (how I solve this problem in C#). So, how do we solve this problem in JAVA?
I thought about this, and have come up with a few not so elegant solution.
1. use factory pattern, define another class which contain the name of that person.
2. covert store object to JSON objects (ObjectNode from jackson), put a new attribute into json objects, return json objects.
3. use reflection to inject a new property to store object, return objects, maybe SpringMVC conversion will generate JSON correctly?
option 1 looks bad, will end up with a lot of boiler plate class which doesn't really useful. option 2 looks ok, but is this the best we could do with springMVC?
option 1
Actually your JSON domain is different from your core domain. I would decouple them and create a seperate domain for your JSON objects, as this is a seperate concern and you don't want to mix it. This however might require a lot of 1-to-1 mapping. This is your option 1, with boilerplate. There are frameworks that help you with the boilerplate (such as dozer, MapStruct), but you will always have a performance penalty with frameworks that use generic reflection.
option 2, 3
If you really insist on hacking it in because it's only a few exceptions and not a common pattern, I would certainly not alter the JSON nodes or use reflection (your option 2 and 3). This is certainly not the way to do it in Java.
option 4 [hack]
What you could do is extend your core domain with new types that contain the extra information and in a post-processing step replace the old objects with the new domain objects:
UnaryOperator<String> toJsonStores = domainStore -> toJsonStore(domainStore);
list.replaceAll(toJsonStores);
where the JSONStore extends the domain Store and toJsonStore maps the domain Store to the JSONStore object by adding the person name.
That way you preserve type safety and keep the codebase comprehensive. But if you have to do it more then in a few exceptional cases, you should change strategy.
Are you looking for a rest service that return list of objects that contain not just one type, but many type of objects? If so, Have you tried making the return type of that service method to List<Object>?
I recommend to create a abstract class BaseRestResponse that will be extended by all the items in the list which you want return by your rest service method.
Then make return type as List<BaseRestResponse>.
BaseRestResponse should have all the common properties and the customized object can have the property name as you said
I am new to neo4j and trying to add multiple values to a property of a node.How to do it?
create (e:Employee{name:"Sam",languages:["C","C#"]})
Tried this but didn't find any proper way to add multiple values to an attribute.
Properties cannot have object values. If you're looking to store multiple properties on language, and those properties all belong to the language and not any other entity, then you should model Language as a node. You can store properties on the relationship between the employee and language as well if required.
Then you'll end up with something like this:
create (l:Language {name:"C", otherProperty:"property value"})
create (e:Employee {name:"Sam"})
create (e)-[:SPEAKS {level:"Fluent"}]->(l)
In fact, you can have array values in properties. You should be able to create them like:
CREATE (n:Node { color: ['Red', 'Blue']})
RETURN n
In your case:
CREATE (e:Employee { name:"Sam",languages: ["C", "C#"]})
RETURN e
is working perfectly fine (you can check it in http://console.neo4j.org/)
Keep in mind that all values in the array must be of the same type, only Strings, or Integers, etc. You can find more info here -> http://neo4j.com/docs/stable/rest-api-property-values.html
However that's not the best approach for that particular example given that C and C# are languages that Sam knows, you should have them as different nodes pointed by Sam through some kind of Knows relationship.
Already referred few question here and there.
Use Case -
1.) Given any Two objects, compare both of them property by property.
2.) It will contains Collections also, now compare collections of both the objects, now inside collection same data can be upside down, meaning say i have List<Address>, it contains two entries in both (say Residential Address, Office Address), but in both list the data may be at different indexes.
3.) Need to create 3rd Object of same type, with similar data copied, and properties set to null with different data.
4.) It might have reference classes as well.
I tired many solutions but stuck somewhere or the other, i am thinking of writing some generic solution. Though of generating two xml's out of the two objects and then comparing node by node, but just want to get more options.
Or How much Java reflection is stronger in this case.
answer to #markspace question.
To access a private field you will need to call the Class.getDeclaredField(String name) or Class.getDeclaredFields() method. The methods Class.getField(String name) and Class.getFields() methods only return public fields, so they won't work.
To access a private method you will need to call the Class.getDeclaredMethod(String name, Class[] parameterTypes) or Class.getDeclaredMethods() method. The methods Class.getMethod(String name, Class[] parameterTypes) and Class.getMethods() methods only return public methods.
XMLUnit will work, it compares the list references recursively, also it has option to exclude fields which you do not wish to compare.
String expectedXML = "some xml";
String actualXML = "some xml";
DetailedDiff diff1 = new DetailedDiff(XMLUnit.compareXML(expectedXML, actualXML));
diff1.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
System.out.println("Differences found: " + diff1.getAllDifferences().toString());
RecursiveElementNameAndTextQualifier
Compares all Element and Text nodes in two pieces of XML. Allows
elements of complex, deeply nested types that are returned in
different orders but have the same content to be recognized as
comparable.
I am using the NamedParameterJdbcTemplate in my Spring app.
I have a data bean object which will hold all my object attributes, "ApplicationVO". The first query, SELECT1_MAIN, populates the core attributes, others will be populated inside a For-loop for each result.
The first query is easy and returns a list of mapped objects (some fields are null). In the second one, I don't want to create separate data beans or any extra code. I want "anonymous" lists that I can step through and add values to my objects.
Some of the extra queries may return multiple fields. Is there an easy way to get anonymous lists without creating extra beans?
// Main Attributes
List<ApplicationVO> allEligibleApps =
jdbcTemplate.query(SELECT1_MAIN, paramMap, new BeanPropertyRowMapper(ApplicationVO.class));
// For each appl., fill out additional attributes
for (ApplicationVO appl: allEligibleApps)
{
List l = jdbcTemplate.query(SELECT2_INFO, paramMap2, BeanPropertyRowMapper(ApplicationVO.class));
appl.setInfoField1(l.get(0));
appl.setInfoField2(l.get(1));
}
NamedParameterJdbcTemplate.queryForList method should do what you ask for.
I've got loads of the following to implement.
validateParameter(field_name, field_type, field_validationMessage, visibleBoolean);
Instead of having 50-60 of these in a row, is there some form of nested hashmap/4d array I can use to build it up and loop through them?
Whats the best approach for doing something like that?
Thanks!
EDIT: Was 4 items.
What you could do is create a new Class that holds three values. (The type, the boolean, and name, or the fourth value (you didn't list it)). Then, when creating the HashMap, all you have to do is call the method to get your three values. It may seem like more work, but all you would have to do is create a simple loop to go through all of the values you need. Since I don't know exactly what it is that you're trying to do, all I can do is provide an example of what I'm trying to do. Hope it applies to your problem.
Anyways, creating the Class to hold the three(or four) values you need.
For example,
Class Fields{
String field_name;
Integer field_type;
Boolean validationMessageVisible;
Fields(String name, Integer type, Boolean mv) {
// this.field_name = name;
this.field_type = type;
this.validationMessageVisible = mv;
}
Then put them in a HashMap somewhat like this:
HashMap map = new HashMap<String, Triple>();
map.put(LOCAL STRING FOR NAME OF FIELD, new Field(new Integer(YOUR INTEGER),new Boolean(YOUR BOOLEAN)));
NOTE: This is only going to work as long as these three or four values can all be stored together. For example if you need all of the values to be stored separately for whatever reason it may be, then this won't work. Only if they can be grouped together without it affecting the function of the program, that this will work.
This was a quick brainstorm. Not sure if it will work, but think along these lines and I believe it should work out for you.
You may have to make a few edits, but this should get you in the right direction
P.S. Sorry for it being so wordy, just tried to get as many details out as possible.
The other answer is close but you don't need a key in this case.
Just define a class to contain your three fields. Create a List or array of that class. Loop over the list or array calling the method for each combination.
The approach I'd use is to create a POJO (or some POJOs) to store the values as attributes and validate attribute by attribute.
Since many times you're going to have the same validation per attribute type (e.g. dates and numbers can be validated by range, strings can be validated to ensure they´re not null or empty, etc), you could just iterate on these attributes using reflection (or even better, using annotations).
If you need to validate on the POJO level, you can still reuse these attribute-level validators via composition, while you add more specific validations are you´re going up in the abstraction level (going up means basic attributes -> pojos -> pojos that contain other pojos -> etc).
Passing several basic types as parameters of the same method is not good because the parameters themselves don't tell much and you can easily exchange two parameters of the same type by accident in the method call.