We have a document management application and a part of it is having customized document forms for the customer to enter document metadata and save it to his database. To create these forms we have developed a 3rd party proprietary application which takes care of the design of the forms (where the fields go, what type they are etc) and then takes this design and creates dynamic tables to represent it in the database. Each form is represented by 3 tables:
Table_A contains information about the form's fields. This table has a standard format and each row in the table represents one of the form's fields.
Table_B contains information about the design. This table also has a standard format and each row contains information about each field's position when dynamically creating the form at runtime.
Table_C contains information about the metadata the user entered when he saved a document in the system. This table does NOT have a standard format. It is dynamically created by the 3rd party software and its columns are dynamic in both number and type. In one form column_A might be an integer and in another form column_A might be a date. One table might have 10 columns while another might have 70. It all depends on the form it represents.
The problem we have at the moment is that we want to add JPA to our project. However, in order to work JPA requires that all persistence models are defined in the xml or through annotations, which is impossible for us because our application doesn't know beforehand the design of Table_C for each form. When we want to retrieve data from that table we actually query Table_A, find out how many fields there are and then build a query dynamically according to the result and query Table_C for its metadata. This technique is impossible to execute in JPQL since it needs concrete objects to create queries. My question is, would it be possible to create persistence models dynamically using DatabaseMetaData and Java's Reflection API?
TL;DR: Is it possible to create JPA persistence models at runtime by reading DatabaseMetaData and using Java's Reflection API?
Related
Now and then I come into the situation that I have to display the table hierarchie of a database for further operations, currently in a data migration project where I have to treat "leaf tables" (tables which are leafes in the table dependency tree) in a different way.
I've always wanted to use Hibernate's meta information to retrieve and display the table dependency tree, but never knew how to approach the problem.
So can anyone give me feedback on whether Hibernate provides an API to do this? I am not asking for a complete solution, the information if there is an API and what it is called is absolutely sufficient.
I want to solve the following questions:
Which tables are in the database?
Is a given table a root table (not dependant from other tables)?
Is a given table a leaf table (dependant from other tables but no table is dependant from the given table)?
Which tables are dependant from the given table?
On which tables does the given table depend?
I know how to retrieve the mapping between entities and tables:
How to discover fully qualified table column from Hibernate MetadataSources , but I want the relationship between the tables.
In a custom MetadataContributor you can access metadataCollector.getDatabase() which exposes the full relational model to you. You just have so save that into a static volatile variable and then access it later on in your app to do whatever you want to do with it.
I have a SAAS product, which is build by Spring MVC and Hibernate. Generally SAAS products allow user's to customize the product like adding extra fields to the table. So i want to give the flexibility to users, to create custom fields in the tables for themselves. Please provide all the viable solutions to achieve it. Thank you so much for your help.
I'm guessing your trying to back this to a Relational database. The primary problem is that relational databases store things in tables, and tables don't really handle free form data well.
So one solution is to use a document structure that is flexible, like XML (and perhaps ditch the database) but databases have features which are nice, so let's also consider the database-using approaches.
You could create a "custom field" table which would have columns (composite primary key) for
ExtendedTable
ColumnName
but you'd also have to store the data somewhere
(ExtendedKey)
DataItem
And now we get into the really nasty bits. How would you apply constraints to this data? I mean, what would the type be of a DataItem? A general solution would be quite complex (being a type of free form database). Hopefully you could limit the solution to solve only the problems you require solved.
Another approach is to use a single "extra" column that contains an XML record which embeds it's own "column and value" extensions, but if you wanted to display a table of the efficiently, you'd have to parse out every XML document in every field, which is not ideal.
Neither one of these approaches will work well with the existing SQL query language, so you'll then start building your own query language.
I suggest you go back and look at real data requirements, instead of sweeping them under the table with a "and anything else one might want" set of columns on your table.
Your requirement is best suited use case for NoSQL databases (like MongoDB).
Dynamically creating relational database tables & columns (modifying schemas) upon user requests in an application is not a best practice as these involve DDL operations, which are very powerful and in case if you don't handle them carefully, the whole application's database goes to the inconsistent state.
Good Afternoon,
We are bulding a web application and as part of it building a search functionality, have a design question on "Search Functionality"
The field names on the UI vs DB are different .i.e. a field on the UI called as "Number" the same is called Text10 in the DB. following are the two issues
How to generate a SQL as user gives the UI field names, we have a table in the DB where we r maintaining configuration(UI name to DB Name)?
User selects the columns which he wants to search, say for example there fields are selected "Number, Description, Price" and once the sql is generated, how to know what data corresponds to what column? Do we have to maintain an index capturing position or a bean?
what is the better way to gather the data based on the resultset?
Thanks
A solution that promotes commonality between UI and database column names would be nice but probably not feasible.
Some sort of mapping table that captures the following will work:
META-DB-TABLE-NAME
META-DB-COLUMN-NAME
META-UI-COLUMN-NAME
Personally I would prefer to keep this mapping meta-data as close to the database as possible.
User-defined meta data is nicely described here from an Oracle perspective:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28369/xdb_repos_meta.htm
Do some research on this and keep us informed with what you find. Very interesting question!
In such a dynamic SQL scenario, query builders like jOOQ really shine. See for example the jOOQ manual section about dynamic SQL.
In your specific case, assuming you're using generated code in jOOQ (which isn't a must, but certainly recommended), you'll be maintaining some sort of lookup between UI fields and SQL fields, such as:
Map<UIField, Field<?>> lookup = ...
lookup.put(UI.NUMBER, TABLE.NUMBER);
lookup.put(UI.DESCRIPTION, TABLE.DESCRIPTION);
lookup.put(UI.PRICE, TABLE.PRICE);
You can then construct your query dynamically according to user needs:
List<UIField> userRequestedFields = ...
List<Field<?>> queryFields = userRequestedFields
.stream()
.map(lookup::get)
.toList();
And then:
ctx.select(queryFields)
.from(TABLE)
.where(...)
.fetch();
There are other query builders, even JPA has the criteria API for these purposes. You could also roll your own, though you'll be re-inventing a lot of wheels.
Disclaimer: I work for the company behind jOOQ.
I'd like to store values of the table created using javafx in data base. Some of values are of the Long type and others are of the object type. For example: there are three tables: "Goods", "Prices" and "TypesOfPrices". in this case the first one has two columns: "id" and "name", the third one has two same columns and the second has 3 fields: "price", "type_of_price", "good". It means that the second table has references to two other tables. I have no need to store references in database as far as I can use their IDs. But from the GUI user needs to have ability to choose value of the "Good" or "TypeOfPrice" type. So the question is What field type shell I choose to have drop down list of records of the other table when the user adds a record. For this purpose the dialog is used.
Ideally, for manipulating data with JavaFX you should use Property. In this way you will be able to bind data to your interface. For example if you want to bind a String to your TextField :
StringProperty myStringProperty = new SimpleStringProperty();
myStringProperty.bind(textfield.textProperty());
For a object TypeOfPrice :
ObjectProperty<TypeOfPrice> objectProperty = new SimpleObjectProperty();
Combobox<TypeOfPrice> typeOfPriceList = ...
objectProperty.bind(typeOfPriceList.getSelectionModel().selectedItemProperty());
In my opinion you should manipulate only property in your controller to make the link between the view and your data.
The boring part come when you want to save these data in your database.
In my first experience, we used H2 + JPA + Hibernate.
We had the model split in two parts, the first model written with Property and the second model written with classical java type like int, String ... that was this second model which was annotated with JPA, and a link was made between these two model.
It looked something like this
Now we changed everything cause hibernate was too slow for our needs, we now use JCR repository for persistence layer. with Modeshape and jcromFX (a fork of Jcrom) for mapping and it works fine, you should take a look at it for alternative to classic H2 DB.
I have followed Balusc's 1st method to create dynamic form from fields defined in database.
I can get field names and values of posted fields.
But I am confused about how to save values into database.
Should I precreate a table to hold values after creating form and
save values there manually (by forming SQL query manually)?
Should I convert name/value pairs to JSON objects
and save?
Should I create a simple table with id,name,value field and
save name/value pairs here (Like EAV Scheme)?
Or is there any way for persisting posted values into database?
Regards
It look like that you're trying to work bottom-up instead of top-down.
The dynamic form in the linked answer is intented to be reused among all existing tables without the need to manually create separate JSF CRUD forms on "hardcoded" Facelets files for every single table. You should already have a generic model available which contains information about all available columns in the particular DB table (which is Field in the linked answer). This information can be extracted dynamically and generically via JPA metadata information (how to do that in turn depends on the JPA provider used) or just via good 'ol JDBC ResultSetMetaData class once during application's startup.
If you really need to work bottom-up, then it gets trickier. Creating tables/columns during runtime is namely a very bad design (unless you intend to develop some kind of DB management tool like PhpMyAdmin or so, of course). Without the need to create tables/columns runtime, you should basically have 3 tables:
1 table which contains information about which "virtual" DB tables are all available.
1 table which contains information which columns one such "virtual" DB table has.
1 table which contains information which values one such column has.
Then you should link them together by FK relationships.