Dynamically create table and Java classes at runtime - java

I have a requirement in my application. My tables won't be defined beforehand.
For example, if a user creates a form by name Student, and adds its attributes like name, roll no, subject, class etc, then on runtime, there should be a table created by name student with columns name, roll no, subject, class etc. And also its related class and its Hibernate mapping file.
Is there any way of doing so?
Thanks in advance,
Rima Desai

Hibernate supports dynamic models, that is, entities that are defined at run-time, but you have to write out a mapping file. You should note a couple things about dynamic models:
You may be restricted in how you define these at run-time (viz. you will have to use the Session directly instead of using a helper method from HibernateTemplate or something like that).
Dynamic models are supported using Maps as the container for the fields of an entity, so you will lose typing and a POJO-style API at run-time (without doing something beyond the baked-in dynamic model support).
All of that said, you didn't mention whether it was a requirement that the dynamically defined tables be persistent across application sessions. That could complicate things, potentially.

It's possible, but it's not clear why would you want to do something like that, so it's hard to suggest any specific solution.
But generally, yes, you can generate database tables, hibernate classes and mappings dynamically based on some input. The easiest approach is to use some template engine. I've used Velocity in the past and it was very good for this task, but there are others too if you want to try them.
EDIT:
Following OP clarification the better approach is to use XML to store user defined data.
The above solution is good but it requires recompiling the application whether forms are changed. If you don't want to stop and recompile after each user edit, XML is much better answer.
To give you some head start:
#Entity
public class UserDefinedFormData {
#Id
private long id;
#ManyToOne
private FormMetadata formMetadata;
#Lob
private String xmlUserData;
}
Given a definition of the form it would trivial to save and load data saved as XML.
Add a comment if you would like some more clarifications.

last week I was looking for same solution and then I got idea from com.sun.tools.javac.Main.compile class, you create the Entity class using java IO and compile using java tools, for this you need tools.jar to locate on CLASS_PATH, now I am looking for run time hibernate mapping without restart.
some one was saying in the post regarding to this type of requirement that "but it's not clear why would you want to do something like that" answer is this requirement is for CMS(Content Management System). and I am doing the same. code is as below.
public static void createClass()
{
String methodName=“execute”;
String parameterName=“strParam”;
try{
//Creates DynamicTestClass.java file
FileWriter fileWriter=new FileWriter(fileName,false);
fileWriter.write(“public class “+ className +” {\n”);
fileWriter.write(“public String “+methodName +“(String “+parameterName+“) {\n”);
fileWriter.write(“System.out.println(\” Testing\”);\n”);
fileWriter.write(“return “+parameterName +“+ \” is dumb\”;\n }\n}”);
fileWriter.flush();
fileWriter.close();
String[] source = { new String(fileName) };
com.sun.tools.javac.Main.compile(source);
}

Related

Is using serialization to store data in a single file a bad idea?

Let's say I have a very simple program that adds/edits/removes and lists products, and I don't want to make the user install a data base in his machine. Would it be a bad idea to store all the products in a single class and then serialize/save it whenever a change is made?
The class would be something like this for example:
public class MyProducts implements Serializable {
private List<Product> products;
public void AddProduct(Product p) {
// Adds a product...
}
public void RemoveProduct(Product p) {
// Removes a product...
}
}
Have in mind that it would be a simple program, nothing critical, just so that I don't need to bother with relational data base in such a simple software.
Scenario 2: In a real software, would it be a good idea to store the program's configuration/preferences in a serialized file?
Thanks!
This is probably a Bad Idea (TM) because:
any change requires rewriting the entire file
there is no data integrity guarantee - no ACID
you cannot, in the future, query the file - everything must be in memory.
I would suggest a file based database. There are literally hundreds of embedded database programs for Java, for example:
HyperSQL
H2
Apache Derby
sqlite
Why not use one of them?
If you do want to store the data in a file consider:
defining serialversionuid so that you can control backwards compatibility
possibly using a human readable format such as JSON, rather than Java serialisation, this also has the advantage of being faster.
To answer your last question, in a "real software" I would expect something like a file-database driven with JPA to be used. With current tools, such a Spring Boot, this is almost configuration free.

Play Model Objects from External API

I'm new in Play 2 Framework v. 2.1.1 with Java and I'm looking for the best way to do the following without duplicating code.
To simplify, I have a Play 2 backoffice that uses an external API. I don't manage this API, but I call REST Services to perform operations over the api.
This API's objects are exactly the same as Play 2 Model Objects. But I don't want to duplicate the api objects to add Play validations and other annotations.
Is there any way to add this type of behavior using configuration files? I'm thinking about something like Hibernate hbm's for example.
For example:
Object in the unmanaged api: (I omit getters and setters for simplicity)
public class Entity{
public String field1;
public String field2;
}
Object that I want to avoid: (I omit getters and setters for simplicity)
public class Entity1{
#Required
#NonEmpty
#MinLength(3)
public String field1;
#Required
#NonEmpty
public String field2;
}
Config example: (I need something like this)
<class name="Entity1">
<property name="field1" >
<required/>
<nonEmpty/>
<minLength value="3"/>
</property>
<property name="field2" >
<required/>
<nonEmpty/>
</property>
</class>
Using annotations seems better than using xmls or any other configuration file, so I don't necessarily want to use configuration files, I'm open to any suggestions to solve this problem.
Thanks
I can't see how duplicating the API model in a non typesafe descriptor like XML is better than using a typesafe language. Moreover, I would not want to couple my model and application to a model from the API under my control.
I think it is far better to duplicate the model in Java/Scala and use a simple bean copier like dozer to move between the two.
One problem is ebean as the persistence provider - in ebean there is no way to externalize the bean persistence configuration as it is possible in hibernate (except for sql queries). Is a switch of the persistence provider possible? Play seems to allow that.
Since you wrote that you are unable to modify the entities source code and you don't want to copy the source, the only other possibility I see is bytecode enhancement.
What you need is a library that would allow you to externalize annotations in a xml file. This library would use the instrumentation api, read the xml file at jvm statup and modify the bytecode of each listed class in order to add annotations to the class and fields at runtime.
There are two problems with this approach:
There is no such library (at least I couldn't find it)
Play and EBean use their own agent / classloader in order to allow hot deployment and persistence
The first problem is the easy and fun part, see for example https://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html. With javaassist it is easy to add annotations to classes and fields. The mapping from xml to annotations is straight foreward. And it would be a nice open source project.
The second problem looks much harder, because you must install your annotation agent so that it executes before play and ebean start to parse the annotations.
It is not clear to me why can't add annotations in your own app, but if you have such constraints why don't you just extend the class, override the variables, add the annotations, and use that as an EBean model?
Play has dynamic forms, which let you validate against a map of key,value pairs. If validation is what you want you could copy an entity's data to a map and validate that.
Simple answer: There is not always code duplication also if the code lines are the same.
Robert C. Martin shows this in one of his talks: the single responsible principle. There are two ways to break this principle: On the one hand two responsibilities in one code fragment on the other hand one responsibility handled independently bei two code fragments.
Code duplication is a matter responsibility and semantics not of code lines that are the same (which may be at most an indicator for having code duplication).
In your case the responsibilities are clearly separated: You have an external API and your code. So there is no code duplication.

Better way to store data in java?

I am currently working on a videogame, and i want to have the user be able to save their character to a new file. I know how to use the file io (for the most part), but i have been using the 'serialize' to serialize a whole object (that contains all the variables for the character) and save it to a file. The problem is that i am constantly updating the object and making changes to it, so when i try to load the old character with the new object, it errors and crashes. Same with levels as-well (an object holding a few 2d-array of variables).
There must be a better way to do this so it is compatible with future versions. If there is a way, would anybody please offer some source code and/or a link to a nice tutorial? All help is appreciated, thanks!!!
Use XML or an embedded database (fast and lightweight) such as Derby or H2. You could even use a plain old properties file.
In fact, see if the properties file will work for you. And only if that won't work, try XML or the embedded database approach.
if you are looking for java serializers here is the benchmark for you https://github.com/eishay/jvm-serializers/wiki/
Apache Avro seems to perform well.
Another way is to store the values in the persistent store like HSQLDB or H2 db and load it to memory at startup and persist when needed.You can also use SQLite (for driver check this)
You can implement Externalizable instead of Serializable, and in the readExternal() and writeExternal() methods you can put the logic to read/write the object. This way you have full control of serialization/deserialization and can make changes fairly easily. Alternatively you can use JSON serialization by using Gson. I would not recommend XML, but if you want to you can check out xstream for the same thing.
If you are extending your objects in backwards compatible ways, i.e. add fields, and not removing fields. Make sure that you have declared a serialVersionUID as per the serializable javadoc.
http://download.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html
One additional option to consider since you're already using serialization, you could implement Externalizable instead of Serializable. The code you use to serialize objects would remain the same. However in your class you would specify exactly how you want it serialized by overriding readExternal() and writeExternal(). E.g.:
public class MyClass implements Externalizable {
private int foo;
private String bar;
public readExternal(ObjectInput in) {
foo = in.readInt();
bar = in.readUTF();
}
public writeExternal(ObjectOutput out) {
out.writeInt(foo);
out.writeUTF(bar);
}
}
Just be sure to keep the order the same when reading and writing. Try to only add fields, however if you need to remove a field leave a gap to account for old versions.
Ultimately though if you're making a lot of changes it might best to switch to a properties or XML file as LES2 suggested. It'll be more portable and readable that way.
This game uses java.util.prefs.Preferences for cross-platform convenience. Because keys are stored individually, new additions rarely interfere with existing entries.

How to stop writing Java property setters for BlazeDS & JPA that I don't want?

BlazeDS will not serialize a property unless it has both a getter and a setter. However, many of my Java properties are read-only. Therefore I am now having to add setters to support the Unmarshalling process. If any of the users of these domain objects start calling these setters themselves it'll break the value-object semantics of these things and likely cause all sorts of system problems.
I've had to do this a lot on the past to support certain aspects of JPA and never liked it. This was because we put our JPA annotations on the properties rather than the private fields (to avoid another problem).
Other than use Javadoc to warn myself and others, what's a programmer to do?
Edit: I should add that these extra setters are NOT part of the public interface these objects implement....but they are still there nonetheless.
You could try using the #Access annotation. This is used to override the access type being used for the class on a column-by-column basis. It also lets you mess with stuff when it goes to the database, like this:
private String firstName;
#Access(AccessType.PROPERTY)
#Column(name="FIRST_NAME")
protected String getFirstNameForDatabase() {
return "Mr. " + this.firstName;
}
This example not only overrides the 'FIELD' access being used for the class, but it also causes the database to commit with "Mr. " prefixed on the value each time. This may also allow you to declare 'dummy' getters/setters that satisfy your other requirements without screwing up the JPA commits and retrieves. Try it out and see if this can be used to craft a solution for your issue.
You have several options: use your own serialization mechanism or use BlazeDS version 4. I wrote a small article related to that, maybe it can help you. The link is http://cornelcreanga.com/2009/09/blazeds-amf-and-read-only-properties/.

simple jdbc wrapper

To implement data access code in our application we need some framework to wrap around jdbc (ORM is not our choice, because of scalability).
The coolest framework I used to work with is Spring-Jdbc. However, the policy of my company is to avoid external dependencies, especially spring, J2EE, etc.
So we are thinking about writing own handy-made jdbc framework, with functionality similar Spring-jdbc: row mapping, error handling, supporting features of java5, but without transaction support.
Does anyone have experience of writing such jdbc wrapper framework?
If anyone has experience of using other jdbc wrapper frameworks, please share your experience.
Thanks in advance.
We wrote our own wrapper. This topic is worthy of a paper but I doubt I'll ever have time to write it, so here are some key points:
we embraced sql and made no attempt to hide it. the only tweak was to add support for named parameters. parameters are important because we do not encourage the use of on-the-fly sql (for security reasons) and we always use PreparedStatements.
for connection management, we used Apache DBCP. This was convenient at the time but it's unclear how much of this is needed with modern JDBC implementations (the docs on this stuff is lacking). DBCP also pools PreparedStatements.
we didn't bother with row mapping. instead (for queries) we used something similar to the Apache dbutil's ResultSetHandler, which allows you to "feed" the result set into a method which can then dump the information wherever you'd like it. This is more flexible, and in fact it wouldn't be hard to implement a ResultSetHandler for row mapping. for inserts/updates we created a generic record class (basically a hashmap with some extra bells and whistles). the biggest problem with row mapping (for us) is that you're stuck as soon as you do an "interesting" query because you may have fields that map to different classes; because you may have a hierarchical class structure but a flat result set; or because the mapping is complex and data dependent.
we built in error logging. for exception handling: on a query we trap and log, but for an update we trap, log, and rethrow an unchecked exceptions.
we provided transaction support using a wrapper approach. the caller provides the code that performs transaction, and we make sure that the transaction is properly managed, with no chance of forgetting to finish the transaction and with rollback and error handling built-in.
later on, we added a very simplistic relationship scheme that allows a single update/insert to apply to a record and all its dependencies. to keep things simple, we did not use this on queries, and we specifically decided not to support this with deletes because it is more reliable to use cascaded deletes.
This wrapper has been successfully used in two projects to date. It is, of course, lightweight, but these days everyone says their code is lightweight. More importantly, it increases programmer productivity, decreases the number of bugs (and makes problems easier to track down), and it's relatively easy to trace through if need be because we don't believe in adding lots of layers just to provide beautiful architecture.
Spring-JDBC is fantastic. Consider that for an open source project like Spring the down side of external dependency is minimized. You can adopt the most stable version of Spring that satisfies your JDBC abstraction requirements and you know that you'll always be able to modify the source code yourselves if you ever run into an issue -- without depending on an external party. You can also examine the implementation for any security concerns that your organization might have with code written by an external party.
The one I prefer: Dalesbred. It's MIT licensed.
A simple example of getting all rows for a custom class (Department).
List<Department> departments = db.findAll(Department.class,
"select id, name from department");
when the custom class is defined as:
public final class Department {
private final int id;
private final String name;
public Department(int id, String name) {
this.id = id;
this.name = name;
}
}
Disclaimer: it's by a company I work for.
This sounds like a very short sighted decision. Consider the cost of developing/maintaining such a framework, especially when you can get it, and it's source code for free. Not only do you not have to do the development yourself, you can modify it at will if need be.
That being said, what you really need to duplicate is the notion of JdbcTemplate and it's callbacks (PreparedStatementCreator, PreparedStatementCallback), as well and RowMapper/RowCallbackHandler. It shouldn't be overcomplicated to write something like this (especially considering you don't have to do transaction management).
Howver, as i've said, why write it when you can get it for free and modify the source code as you see fit?
Try JdbcSession from jcabi-jdbc. It's as simple as JDBC should be, for example:
String name = new JdbcSession(source)
.sql("SELECT name FROM foo WHERE id = ?")
.set(123)
.select(new SingleOutcome<String>(String.class));
That's it.
Try mine library as alternative:
<dependency>
<groupId>com.github.buckelieg</groupId>
<artifactId>jdbc-fn</artifactId>
<version>0.2</version>
</dependency>
More info here
Jedoo
There is a wrapper class called Jedoo out there that uses database connection pooling and a singleton pattern to access it as a shared variable. It has plenty of functions to run queries fast.
Usage
To use it you should add it to your project and load its singleton in a java class:
import static com.pwwiur.util.database.Jedoo.database;
And using it is pretty easy as well:
if(database.count("users") < 100) {
long id = database.insert("users", new Object[][]{
{"name", "Amir"},
{"username", "amirfo"}
});
database.setString("users", "name", "Amir Forsati", id);
try(ResultSetHandler rsh = database.all("users")) {
while(rsh.next()) {
System.out.println("User ID:" + rsh.getLong("id"));
System.out.println("User Name:" + rsh.getString("name"));
}
}
}
There are also some useful functions that you can find in the documentation linked above.
mJDBC: https://mjdbc.github.io/
I use it for years and found it very useful (I'm the author of this library).
It is inspired by JDBI library but has no dependencies, adds transactions support, provides performance counters and allows to switch to the lowest possible SQL level in Java (old plain JDBC API) easily in case if you really need it.

Categories

Resources