Hibernate. How to create an empty table from ResultSetMetaData? - java

I have a ResultSetMetaDataobject.
PreparedStatement ps=con.prepareStatement("select var1, var2 from test1, test2");
ResultSet rs=ps.executeQuery();
ResultSetMetaData rsmd=rs.getMetaData();
System.out.println("Total columns: "+rsmd.getColumnCount());
System.out.println("Column Name of 1st column: "+rsmd.getColumnName(1));
System.out.println("Column Type Name of 1st column: "+rsmd.getColumnTypeName(1));
I need to create an new empty table with all the fields in the above ResultSetMetaData
Open a new connection in different database
Use the meta data above
Create a new empty table with this meta data
I can see two possible solutions
Reflection. In general to create a table with Hibernate, I need to create a bean. But I don't know in advance what fields the ResultSetMetaData will contain . Should I create this bean with reflection?
HQL CREATE TABLE . Is this possible?
What is the simplest way to do this? How can I do this?

Couple of solutions that I can think of:
SchemaExport - Iterate through your ResultSetMetaData which exposes API's like getColumnName and getColumnType to get the information you need. Using this information create a hibernate mapping XML and send it to SchemaExport.create.
// yourClassMapper.xml generated in runtime
Configuration config = new Configuration();
config.addResource("yourClassMapper.xml");
new SchemaExport(config).create(true,true)
Native Query - As Usual Iterate through your metadata to figure out what should the columns be.
Using createSQLQuery or even using createNativeQuery
session.createSQLQuery("create table .....").executeUpdate();
This link provides an explanation on how to create custom fields. You can make use of its DOM Parser for 1st approach or create just tables and use the method mentioned in this blog to create custom fields. (Refer to this class MappingManager and its related custom map configuration)
Lastly, You need 2 different datasource to be configured for this. And inject the second database's source for creating session/sessionfactory in above implementations.

I dont think you need to create bean for it. If you want to create new table with same fields then simple fire this query on database using hibernate or jdbc.
SHOW CREATE TABLE tablename
Now simply change the name of the table in query, can be easily done in Java.
Now you does not need to create any bean for newly created table.
There are two ways for fetching data from table in hibernate. First way is get table data in form of bean object, another way is fire sql query and get data in form of Object (Java Class). you can get data in form of Object and Object Array using hibernate.
When we use join query in hibernate, then there is no specific type of bean is available for handling result of join because it contain column from multiple table so you will get data in form of Object and Object Array.
Just get Data in form of Object or Object Array.
Check This Link of my github... not exactly what you want but still will help :
here
I hope I Helped you.

Related

Access user defined method properties on query - Esper

I implemented a query where i mined data from a database but i have to change it so i mine my data from a custom function in my code. I read the documentation and added the annotation import on the configuration. The query throws that error:
Failed to resolve event type, named window or table by name 'path.to.my.class.customfunction'
I don't know the type that my function have to return but i tried Arraylist and Hashmaps with key an integer and value a custom class and didn't work.
My final query want to look like this :
select * from LocationEvent as loc,
***CustomFuntion()*** as product
where loc.id=product.id ;
I kept the structure i used for database connection. I don't know if there is another way to solve this. Thanks.
EDIT: I managed to make call the custom function with that query :
select path.to.class.getProducts() as product from pattern[every timer:interval(3 sec)]
My function right now return an ArrayList and the query returns this:
[Product{ProductID=124,.....,},Product{...}]
So now my problem is that i can't access properties of Product on the query like products.ProductID
If you want to have a custom function in the from-clause you can use the "method:". The docs have this described here: Accessing Non-Relational Data via Method. The Esper runtime then calls your method to get events/rows.

Custom query with JPA DataTables (jquery Datatables)

I'm building a web page where I get a jquery DataTable with a list of rows connected to the id of a field I'm passing through the form.
I'd like to create a DataTable that uses a sort of "native query" using a parameter inside the method of my controller.
Something like:
#Query("Select * from ... where ...=:id ", native="true")
public DataTablesOutput <Object> findByField (#Param(value="id")id, input);
I know it doesn't work, but I haven't understood at all how Specification and QueryDSL work with the DataTable repository, so could someone please make a simple example with objects instead of generics?
(The id I'm passing is a column of the resultSet from the Database, but it's not mapped in the object I get on java, because I'm trying to make the query lighter and nonrecursive)

Get data through Hibernate without Entity classes

We use Hibernate and annotations to map our db and entities. But for some data tables I don't want entity classes (Because these table names and all are keep changing) so that the application will be more dynamic
So is it possible using hibernate to load data from a table without a entity class?
If so how?
Hibernate provides a way to execute SQL query and to map it to an entity or any class : native sql queries.
Use plain JDBC. I'm not sure what you mean by "table names and all are keep changing" but it sounds like a bad idea to me.
What you could do is create the sql query using string concatenation then use plain JDBC to execute it. That way you can keep table names dynamic.
If Persistence class won't be used, then the data encapsulation won't occur thus data can be accessed directly.
Hibernate Queries interact with the POJO class to fetch data.
Query, Criteria, HQL all the classes use the POJO for fetching data.
Hibernate Framework was mainly designed for the ORM Mapping.
Thus without POJO class, not possible to interact with the database.
Thus using JDBC connection would be the option left.
Use Dynamic models introduced in Hibernate 5 version - 5.4.0.Final
Hibernate Dynamic Models
To achieve this you will need HBM files created.
Session s = openSession();
Transaction tx = s.beginTransaction();
Session s = openSession();
// Create a customer
Map david = new HashMap();
david.put("name", "David");
// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");
// Link both
david.put("organization", foobar);
// Save both
s.save("Customer", david);
s.save("Organization", foobar);
tx.commit();
s.close();
Here Customer & Organization are table names
Organization is Parent of Customer.
Click on the above link for more details

How to insert an object(more than 10 properties) into mysql via mybatis based on annotation without list all properties

I want to insert an Object with more than 10 properties into mysql via mybatis based on annotation. But I must list all properties, it's too inconvenient. I want to know is there some ways to insert an object easily without list all properties via mybatis. Here is my snippet. Thanks a lot.
#Insert("insert into poi_shop(name,brand,tags,status,phone,mobile,business_time,address,city,lng,lat,business_type,attribute_json) values(#{name},#{brand},#{tags},#{status},#{phone},#{mobile},#{business_time},#{address},#{city},#{lng},#{lat},#{business_type},#{attribute_json})")
#Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public Long insertPoiInfo(PoiBo poiBo);
It is not possible in MyBatis (at least version 3) out of the box.
MyBatis has auto mapping when reading data from database but doesn't have option to automatically map fields on insertion.
The reason for this is that MyBatis is very SQL centric that is you need to write SQL manually. It is possible to have implicit fields in SQL select statement (select * from table) so there is automatic mapping to POJO in this case but it is not possible to have implicit fields in update or insert hence no auto-mapping.
MyBatis can be extended of cause. For example you can use #InsertProvider/#UpdateProvider with the sql generator that generates sql using reflection to get object fields.

Is it possible to 'automate' updates to Prepared Statements when new fields are added to database/bean class?

Long time no see!
I'm in the process of creating a web application and wanted to speed up the process of updating Prepared Statements when new fields are added to the XSD that generates my JavaBean class and corresponding database table. Here's the process in order:
Add field to database table
Update XSD with variable added as element
Generate JavaBean class using XJC
Once the class has been rewritten with the updated fields and corresponding getter/setter methods, it's "available" to be set.
However, the issue still stands that I have to go into my DAO class for the class and update the resultSet and 'get' the field.
String foo = resultSet.getString("TABLENAME_foo");
Then, I have to set the class instance for the method:
instanceObj.setFoo(foo);
Any ideas on how I'd go about automating this process? This is a relatively simple thing to update, but the point is, I want as much automation as possible.
I'm not looking to use any form of plugin, addons, etc. nor an ORM solution.
You can generate the DAO class out of the XSD files. Then you can get/set the values for each field defined there.
An alternative is to create a generic method in the DAO which either uses introspection to find out about the properties or analyzing the XSD and use those infos to set the properties properly.
You can use ResultSetMetaData from ResultSet
ResultSetMetaData metadata = resultSet.getMetaData();
int columnCount = metadata.getColumnCount();
for (int i=1; i<=columnCount; i++)
{
String columnName = metadata.getColumnName(i);
}
Then use Reflection to set the instance.
But in this case, the instance's field name has to be same as DB column name.
Or you can use SELECT TABLENAME_foo as fieldName FROM *** to work around.

Categories