Can a Derby database contain rows with different numbers of columns? - java

ie, I want to dynamically create extra columns for specific users if required from the JSP pages of my web app - is this possible, or is there another way of achieving the same thing?

Short answer is no. Every row in a table must have the same number of columns.
If there is no applicable value for a column one typically inserts NULL (SQL NULL which is different from Java null). Alternatively you could change your data model and put the optional values in a different table, and use a join when you want to read the optional columns.
Finally, you could also represent the optional info in a Java object and serialize that into a Blob which you store in your table, but I would caution you against this approach since it prevents you form querying on the values in the Blob and you get an upgrade problem if the format of the Blob object changes.

Hibernate allows you to dynamically create database table provided
you know rows and columns
If you dont want to add that and still keep it simple and sweet use "<% scriptlet %>" codes in jsp containing Java code to create or modify table
Instead of using scriplet you could use Struts / JSF/ Spring tags for cleaner code

Related

Get the database fields programmatically in Java

I have a jrxml file (sample shown below) which has the database query embedded in it. Now this query will return different columns against different databases. Since the columns are varying, I am planning to programmatically load the jrxml file, read the fields returned from the query (embedded in jrxml) and then place them on the jrxml
Have 2 questions
How do I get the field names returned from the query (embedded in jrxml)
How do we iterate through those fields so that they can be placed on the jrxml
Amy sample code would be appreciated.
Please note my preference is to use Jasper API's only.
How do you intend to query the database if you do not know the column names? The only case I can think of is that you are always going to select all the columns.
What I think you need is a parameterized query which will allow you to pass column names as parameters. See this page on using report parameters.
If you really want to always select all the table columns then before filling the report you will have to retrieve the table metadata and pass the column names to the report as parameters. If you are using JDBC then you simply need to call java.sql.Connection.getMetaData() and query the MetaData object for column names. However, hardcoding SELECT * is potentially dangerous because your result sets will keep growing in size as new columns get inserted into the table.

Java Displaytags: custom column with form and action

Java Tomcat application.
I am using displaytags to render tables with data.
I am passing the List from my application and JSP displaytags is just rendering it (and displaying). I need to use displaytags to have a possibility to sort tables based on different columns.
But right now i need to have the action (form) for each row - to have a possibility to remove that record from mysql database.
Is there any possibility to add one more column using a custom value (with a form with custom value derived from every record id) ?
Thanks,

How to load dynamic content in JSF table

I have a webpage with a table layout in it which is develop using JSF. The data, including header and content value, inside the table should be dynamically load. My current challenge is different source coming into this JSF page will have different row's of records. May I know how this can be done? Am I require a Java Bean to achieve my objective?
You can easily use beans for that. Usually the content of the table will go from the database. So in the datatable you can just use value="#{yourbean.contentList}". And the contentList will be retrieved based on the id of the desired data which can be set by the request params.
JSF datatable do not have a limit on the number of rows. If there are a large number of rows the browser may not handle it well, use paging to limit the number of rows http://balusc.blogspot.com/2008/10/effective-datatable-paging-and-sorting.html
If there are different numbers of columns (not rows) in the data then dynamically generate datatable http://balusc.blogspot.com/2006/06/using-datatables.html#PopulateDynamicDatatable
Thanks to BalusC!

Hibernate: adding an object if not already present

Here's the case: I am creating a batch script that runs daily, parsing logfiles and exporting the data to a database. The format of this file is basically
std_prop1;std_prop2;std_prop3;[opt_prop1;[opt_prop2;[opt_prop3;[..]]]
The standard properties map to a table with a column for each property, where each line in the logfile basically maps to a corresponding row. It might look like LOGDATA(id,timestamp,systemId,methodName,callLenght). Since we should be able to log as many optional properties as we like, we cannot map them to the same table, since that would mean adding a row the table every time a new property was introduced. Not to think of the number of NULL references ...
So the additional properties go in another table, say EXTRA_PROPS(logdata_foreign_key,propname,value). In reality, most of the optional properties are the same (e.g. os version, app container, etc), making it somewhat wasteful to log for instance 4 rows in EXTRA_PROPS for each row in LOGDATA (in the case that one on average had 4 extra properties). So what I would like my batch job to do is
for each additionalProperty in logRow:
see if additionalProperty already exist
if exists:
create a reference to it in a reference table
if not:
add the property to the extra properties table
create a reference to it in a reference table
I would then probably have three slightly different tables:
LOGDATA(id,timestamp,systemId,methodName,callLenght)
EXTRA_PROPS(id,propname,value)
LOGDATA_HAS_EXTRA_PROPS(logid,extra_prop_id)
I am not 100% this is a better way of doing it, I would still create N rows in the LOGDATA_HAS_EXTRA_PROPS table for N properties, but at least I would not add any new rows to EXTRA_PROPS.
Even if this might not be the best way (what is?), I am still wondering about the tecnhical side: How would I implement this using Hibernate? It does not have to be superfast, but it would need to chew through 100K+ rows.
Firstly, I would not recommend using Hibernate for this type of logic. Hibernate is a great product but doing this kind of high load data operations may not be it's strongest point.
From data modeling standpoint, it appears to me that (propname,value) is actually a primary key in EXTRA_PROPS. Basically, you want to express the logic that, for example, hostname + foo.bar.com combination will only appear once in the table. Am I right? That would be PK. So you will need to use that in LOGDATA_HAS_EXTRA_PROPS. Using name alone will not be sufficient for reference.
In Hibernate (if you choose to use it), that can be expressed via composite key using #EmbeddedId or Embeddable on object mapped to EXTRA_PROPS. And then you can have many to many relationship that uses LOGDATA_HAS_EXTRA_PROPS as association table.

LinkedList with Serialization in Java

I'm getting introduced to serialization and ran into some problems when pairing it with LinkedList
Consider i have the following table:
CREATE TABLE JAVA_OBJECTS (
ID BIGINT NOT NULL UNIQUE AUTO_INCREMENT,
OBJ_NAME VARCHAR(50),
OBJ_VALUE BLOB
);
And i'm planning to store 3 object types - so the table may look like so -
ID OBJ_NAME OBJ_VALUE
============================
1 Class1 BLOB
2 Class2 BLOB
3 Class1 BLOB
4 Class3 BLOB
5 Class3 BLOB
And i'll use 3 different LinkedList's to manage these objects..
I've been able to implement LoadFromTable() and StoreIntoTable(Class1 obj1).
My question is - if i change an attribute for a Class2 object in LinkedList<Class2>, how do i effect the change in the DB for this individual item? Also take into account that the order of the elements in LinkedList may change..
Thanks : )
* EDIT
Yes, i understand that i'll have to delete/update a row in my DB table. But how do i keep track of WHICH row to update? I'm only storing the objects in the List, not their respective IDs in the table.
You'll have to store their IDs in the objects you are storing. However, I would suggest not trying to roll your own ORM system, and instead use something like Hibernate.
If you change an attribute in a an object or the order of items. You will have to delete that row and insert the updated list again.
How do i effect the change in the DB for this individual item?
I hope I get you right. The SQL update and delete statements allow you to add a WHERE clause in which you chose the ID of the row to update.
e.g.
UPDATE JAVA_OBJECTS SET OBJ_NAME ="new name" WHERE ID = 2
EDIT:
To prevent problems with your Ids you could wrap you object
class Wrapper {
int dbId;
Object obj;
}
And add them instead of the 'naked' object into your LinkedList
You can use AUTO_INCREMENT attribute for your table and then use the mysql_insert_id() function to retrieve the id assigned to the row added/updated by the last INSERT/UPDATE statement. Along with this maintain a map (eg a HashMap) from the java object to the Id. Using this map you can keep track of which row to delete/update.
Edit: See the answer to this question as well.
I think the real problem here is, that you mix and match different levels of abstraction. By storing serialized Java objects into a relational database as BLOBs you have to consider several drawbacks:
You loose interoperability. Applications written in other languages than Java are not able to read the data back. Even other Java applications have to have the class files of the serialized classes in their classpath.
Changing the class definitions of the stored classes will end up in maintenance nightmares.
You give up the advantages of a relational database. Serialization hides the actual data from the database. So the database is presented only with a black box. You are unable to execute any meaningfull query against the real data. All what you have is the ID and block of bytes.
You have to implement low level data handling by yourself. Actually the database is made to handle your data effectively, but because of serialization you hinder it doing its job. So you are on your own and you are running into that problem right now.
So in most cases you benifit from separation of concerns and using the right tool for a job.
Here are some suggestions:
Separate the internal data handling inside your application from persistent storage. Design your database schema in a way to enable the built-in database features to handle the data efficently. In case of a relational database like MySQL you can choose from different technologies like plain JDBC, object relational mappers like JPA or simple mappers like MyBatis. Separation here means to avoid to contaminate the database with implementation specific concerns.
If you have for example in your Java application a List of Person instances and each Person consists of a name and an age. Then you would represent that list in a relational database as a table consisting of a VARCHAR field for the name and a numeric field for the age and maybe a third field for a unique key. Then the database is able to do what it can do best: managing large amounts of data.
Inside your application you typically separate the persistent layer from the rest of your program containing the code to communicate with the database.
In some use cases a relational database may not be the appropiate tool. Maybe in a single user desktop application with a small set of data it may be the best to simply serialize your Person list into a plain file and read it back at the next start up.
But there exists other alternatives to persist your data. Maybe some kind of object oriented database is the right tool. In particular I have experiences with Fast Objects. As a simplification it is serialization on steroids. There is no need for a layer like JPA or JDBC between your application and your database. You are able to store the class instances directly into the database. But unlike the relational database with its BLOB field, the OODB knows your classes and the actual data and can benefit from that.
Another alternative may be JDBM or Berkeley DB.
So separation of concerns and choosing the right persistence strategy (and using it the right way) is a key concern for the success of your project. But doing it right is hard even for experienced developers.

Categories