Given some sort of document object model with methods like int getInt(String col), getFloat, getString, getDate, etc., and classes wither either plain public fields, or public setters such as setName(String), setAge(int), etc. I want to map my document record to the specified Java type.
I have seen this done with various large JSON, SQL, etc. libraries, just by taking say MyRecordObject.class at run time, no compile time code gen using any sort of schema files.
But how is this implemented? Does Java have some sort of low-level interface for representing a DOM/record structure and mapping it to specific Java classes?
//to create something like this
Record record = readRecordFromMyGenericFileFormat();
TodoItem todo = record.as(TodoItem.class);
The general idea is to use reflection to dynamically set the values of fields in an instance of a Class.
Apache BeanUtils might be useful and save you some trouble. Example
Employee employee = ...;
PropertyUtils.setSimpleProperty(employee, "firstName", firstNameValue);
PropertyUtils.setSimpleProperty(employee, "lastName", lastNameValue);
You'd have to fetch the field name ("firstName") and value (firstNameValue) from your generic file format.
If the field name information is not available in your file format, perhaps getting the fields dynamically via reflection could work for your use case.
There are multiple high quality tutorials on Java Reflection online.
Related
in hibernate to create criteria we use
Criteria criterea=session.createCritera(SomeClass.class)
It may be available in some other examples too but I am not able to understand the structure of these type of methods.
NOTE this is an example I am trying to put to understand use of SomeClass.class like arguments
my question here is what is purpose of SomeClass.class ? why do we need it, what is the advantages of using it as argument.
Edit its not a duplicate but have string connection to this question
What is this .class syntax?
If you attach .class to the end of a class name, you get the Class<T> object corresponding to the class.
Examples:
String.class returns an instance of Class<String>
Integer.class returns an instance of Class<Integer>
What can you do with a class object
Reflection! If you have access to a class object, you can do all kinds of cool stuff! You can call methods, get and set values of fields...
Why is this used in Hibernate?
I haven't used hibernate before, but this syntax is used in other libraries as well, especially in ORMs or JSON serializers. I'll use JSON serializers as an example as I'm more familiar with those.
In a JSON serializer, you need to give it a class object because it needs to get all the fields that you want to serialize to JSON. It uses reflection to get and set the values of those fields, then convert them to JSON. When it deserializes JSON, it finds the field that needs to be set with the name in the JSON. These operations require a Class object because without it, how can Java know which class should it find the field? Also, to create a new object with reflection, a Class is needed as well!
Hibernate provides many ways to handle the objects in relation with RDBMS tables.
One way is Session interface providing createCriteria() method which can be used to create a Criteria object.
As name says criteria, it is useful to execute queries by applying filtration rules and logical conditions of programmer wish.
For example:
Criteria obj=session.createCritera(Galaxy.class) // say SomeClass is Galaxy.class
List results = obj.list();
Here, criteria query is one which will simply return every object that corresponds to the Galaxy class.
We even can restrict the results with criteria, example add() method available for Criteria object to add restriction for a criteria query.
Following is the restriction to return the records with planet which has 7.4 billion population from Galaxy class:
Criteria cr = session.createCriteria(Galaxy.class);
cr.add(Restrictions.eq(“planet”, 75000000000));
List results = cr.list();
I am designing an application that has two widgets:
-A list that contains arbitrary objects
-A table that displays specific properties of the currently selected object
The goal is to be able to pick an object from the list, look at the properties, and modify them as necessary. The list can hold objects of various types.
So say the list contains Vehicle objects and Person objects
public class Person
{
public String name;
public Integer age;
}
public class Vehicle
{
public String make;
public String model;
}
If I click on a Person object, the table will display the name and age, and I can assign new values to them. Similarly, if I click on a Vehicle object, it will display the make and model in the table and allow me to modify them.
I have considered writing a method like
public String[] getFields()
{
return new String[] {"name", "age"};
}
Which returns a list of strings that represent the instance variables I want to look at, and use some reflection methods to get/set them. I can define this getFields method in all of the classes so that I can use the table to handle arbitrary objects that might be thrown into the list.
But is there a way to design this so that I don't resort to reflection? The current approach seems like bad design.
On the other hand, I could create multiple TableModel objects, one for every possible class. The table would know what rows to display and how to access the object's instance variables. But then everytime a new class is added I would have to define a new table model, which also sounds like a weak design.
You have a class (Vehicle) and you know the names of some properties (make, model) that you want to be able to manipulate dynamically for an instance of this class through a JTable UI.
You have various different approaches to chose from.
A. Use the reflection API
This is what the reflection API is made for. If you want something so dynamic, there is nothing wrong with using reflection. The performance overhead will not be significant for this use case.
B. Use a library like beanutils that is based on the reflection API
This should be easier than directly using the reflection API, but it has the drawback that you need to include another dependency in your project.
C. Create dynamically at runtime the different TableModel classes.
You can do this using either the java compiler API or javassist. Based on information available at runtime, you are able to compile a new class for each different type of table model. If you follow this approach you must be aware that the creation of the class is a heavy task, so the first time you create a TableModel the application will take some time to respond.
What to chose?
Of course this is your decision. For the specific use case, the overhead added by reflection or beanutils is insignificant, so probably it is better to chose between A or B. In another use case where performance is more critical, then you could examine the C approach, without forgetting the class creation response time problem.
EDIT:
I just realized that in this specific use case there is another important functionality required. Convert from String to the appropriate data type of each property and vice cersa. Beanutils has perfect support for that, so it gets a plus here.
AppEngine only supports "TABLE_PER_CLASS" and "MAPPED_SUPERCLASS" for JPA inheritance.
Unfortunately "JOINED" and especially "SINGLE_TABLE" are not supported.
I'm wondering what the best alternative is to implement a SINGLE_TABLE alternative?
My only requirements are:
1) Have separate classes like AbstractEmployee, InternalEmployee, ExternalExmployee.
2) Being able to run a query over all employees, thus resulting in both InternalEmployee and ExternalEmployee instances.
The only thing I'm thinking off is using a 'big' Employee object containing all fields?
Any other ideas?
PS: vote for proper "SINGLE_TABLE" support via http://code.google.com/p/googleappengine/issues/detail?id=8366
You could in theory use #Embeded and #Embeddable to group related fields into an object. So you would have a class that looks something like.
#Entity
public class Employee {
// all the common employee fields go here
//
// the discriminator column on Employee class lets you be specific in your queries
private Integer type;
#Emebded
private Internal internal; // has the fields that are internal
#Embeded
private External external; // has the fields that are external
equals & hashcode that compare based on the discriminator type and other fields
}
What AppEngine supports and doesn't support is misleading there. AppEngine uses a property store, so any Kind can have any properties. Consequently, in principle, a Kind can contain InternalEmployee and ExternalEmployee "instances". The only thing that AppEngine JPA actually does is store all fields of a class in a single Kind object. That doesn't preclude having subtypes stored in the same Kind (with extra properties for the subtype-specific fields), which is the equivalent of "single-table".
PS, raising some issue on "AppEngine" as a whole won't get any response (look at the rest of issues in there ;-) ), bearing in mind the code affected here is in its own project at http://code.google.com/p/datanucleus-appengine and has its own issue tracker
I have some POJOs that are used to shuffle data around in my application and its webservices. We have just introduced an annotation to help us verify that String fields in those POJOs are of a certain length. This lets us validate the POJOs instead of waiting for the database layer to puke out an exception when it persists.
I would now like to do an analysis on those objects that will tell me what fields are Strings that do not have this new annotation. I want to do this so that I can get a list of fields that do not have this annotation so that it can be compared to its corresponding DB field and have the annotation added with the right length as its parameter.
No we cannot get a better correlation between our POJOs and our database objects.
No our database objects don't have this validation available. We really want this validation to happen on the POJOs as it is simpler to validate and report on invalid data at runtime.
Is there some static analysis tool that would help me with this task?
Sure.
Parse the Java code. Walk the AST. Find the fields of interest (may require that you also do name and type resolution ("symbol tables") so you can tell your fields from arbitary other fields) in the ASTs for your classes, and inspect the AST for the desired annotation.
You can do this with any Java AST parser (and name resolver). I think Eclipse can provide this. Our DMS Software Reengineering Toolkit can do this. ANTLR appears to have a Java parser, but I doubt if it has Java name and type resolution.
I opted to use annotations for the runtime validation needs and then crafted a unit test to verify that all fields were annotated. This was inspired by #c0mrade .
So the annotation is #Length and requires an integer parameter. At runtime the validator iterates over fields and looks for the #Length annotation and makes sure its applied on a String field. It then looks at the length of the Strings value and makes sure it is less than or equal to the parameter for the annotation.
In a unit test I load all of the classes for my POJOs by package. I then iterate over those classes, iterate over each classes fields, and finally check and see if the field is a String and has the #Length annotation assigned. If the field is a String and does not have #Length, it adds the class and field name to a list of Strings. The assertion for the test is that this list is empty.
I need to create an enum based on a table from the database.
DB table MyColors: id/title/value
1/Red/1
2/Green/4
dynamic create
enum MyColors {
Red=1,
Green=4;
}
You can dynamically create source code by reading from the database and simply outputting the results in a format conducive to building an enum. However, it is impractical to create an enum at run time. You would be better off with some kind of associative array.
Actually there is a possibility of dynamically creating enums using reflection: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically
One option to is to define an XML Schema and the required values as enum and generate the class files, so that we can manage the values outside the source code, however we cannot dynamically generate the enum values from the database.
It's not clear if you want to generate source code or not. I guess not, since even compiled no code in the same program could access the the enum objects except through reflection.
So why not mapping the table to a ColorEntity object using JPA?
You can then have a list or a map of these entities or whatever you need.