how do you easily create tables in spring mvc - java

I have a spring mvc project that needs to create a bunch of tables. The source of the table data is from a non-SQL, remote data source that isn't available until after the user logs in. I can create dummy rows in DataConfiguration.initDatabase and then truncate each table. If I don't do that, then when I try to insert data in other places in the code, the reference to the repository is null.
Since I have quite a number of tables and they use referential integrity, is there a way to declare them in such a way that they are automatically created without actually inserting any data?
I am using Java configuration.

The tables were apparently created after all. Even when I looked in H2, I couldn't find them. Turns out I was looking in the default H2 connection "jdbc:h2:~/test" rather than "jdbc:h2:mem:testdb".

Related

Obtain copy of existing object with Hibernate and Spring Boot

I have the following tricky situation in my Spring Boot application that uses Hibernate. I load objects from the data store and I modified them in several functions of my application that are not related one with another. The idea is that I need to load the existing copy of the object from the database before saving its update instance in order to create a backup, but if I use the repository's findById method, Hibernate finds a copy of the object (the modified one) in its cache and returns that one and it is not ok for me, because I need a copy of the original object, before it was modified (the object that is currently in the database). I tried using a separate Session, but in case of multiple objects the DB is locked and I'm not able to access the database anymore (MS Sql Express). Has anyone an idea on how to obtain the original unmodified object before persisting tghe changes in the database ? Thanks
To keep backup of entities you should use #Audited (it keeps versions / snaphshots of each entity).
You can have a look over there https://www.baeldung.com/database-auditing-jpa
A more advanced approach is https://javers.org/.
Javers is the state-of-the-art way to do what you want to do. I think it will suit your needs.

Is there a way to get data from table without repository and entity?

We have 2 projects with the same database using JAVA Spring-boot. The main projects hold the entity and repository files. Which is different to the other project. Since we don't understand the whole system of the main project we create ours. The problem is I need to get the data from a table without using repositories function like get, save, etc. I just need to query the table. Is this possible?
Thank you.
Depends on what you want
Only simple Data
A complete Object representing the data or part of the data
For the first one I would take JDBC(https://www.javatpoint.com/java-jdbc)
For the second one I would take JPA/Hibernate.
You can create a Entity which represents only the data you need and make it read-only(How to make an Entity read-only?).
And then you can create a simple CrudRepository/JpaRepository where you fetch the data.
Here's some pointers for your help:
DB Name/Host/User/Pass should be found in one of the *.properties files.
In Repositories, the table names are usually with #Table annotation.
To know what Queries a particular repository can execute, you can check with #Query annotation. Or the methods inside the repository may donate queries, like findByStudentId means select from student where id=.
Now with the above clues, you can just write a simple JDBC connection (it really depends on what db it is in the backend), connect to the DB above, and execute the queries you may want to.

Creating tables dynamically in Hibernate environment

There's an enterprise application using Java + Hibernate + PostgreSQL. Hibernate is configured via annotations in the Java source code. So far the database schema is fixed, but I faced the problem that it needs to be dynamic:I can receive data from different locations and I have to store these in different tables. This means that I have to create tables run-time.
Fortunately, it seems that all of these data coming from the different institutes can have the same schema. But I still don't know how to do that using Hibernate. There are two main problems:
How to tell to Hibernate that many different tables have the same structure? For example the "Patient" class can be mapped to not just the "patient" table, but the "patient_mayo_clinic" table, "patient_northwestern" table, etc. I can feel that this causes ambiguity: how Hibernate knows which table to access when I do operations on the Patient class? It can be any (but only one) of the former listed tables.
How can I dynamically create tables with Hibernate and bind a class to them?
Response to suggestions:
Thanks for all of the suggestions. So far all of the answers discouraged the dynamic creation of tables. I'll mark Axel's answer, since it achieves certain goals, and it is a supported solution. More specifically it's called multi-tenancy. Sometimes it's important to know some important phrases which describes our problem (or part of our problem).
Here are some links about multi-tenancy:
Multi-tenancy in Hibernate
Hibernate Chapter 16. Multi-tenancy
Multi-tenancy Design
EclipseLink JPA multi-tenancy
In real world scenario multi-tenancy also involves the area of isolating the sets of data from each other (also in terms of access and authorization by different credentials) once they are shoved into one table.
You can't do this with Hibernate.
Why not extend your patient table with an institute column?
This way you'll be able to differentiate, without running into mapping issues.
I am afraid you can't do this easily in Hibernate. You would have to generate the Java source, compile it, add it to your classpath and load it dynamically with java.reflection package. If that works, which I doubt it, it will be an ugly solution (IMHO).
Have you consider using a schema less database i.e: NoSQL databases or RDF
databases. They are much more flexible in terms of what you can store in them , basically things are not tight up against a relational schema.
In most environments it is not a good idea to create tables dynamically simply because dbas will not give you the rights to create tables in production.
Axel's answer may be right for you. Also look into Inheritance Mapping for Hibernate.
I agree that its not advisable to create tables dynamically nevertheless it's doable.
Personally i would do as Axel Fontaine proposed but if dynamic tables is a must-have for you I would consider using Partitioning.
PostgreSQL allows you to create ona main table and few child tables (partitions), records are disjunctive between child tables, but every record from any child table is visible in parent table. This means that you can insert rows into any child table you want using just simple insert statement (its not cool but has the same level of complexity as composing and persisting an entity, so its acceptable in your case) and query database using HQL

How to map dynamically created table in Hibernate?

I am working on a web application. We are using Hibernate as ORM in our project. Actually, our application creates some tables dynamically based on user selection. The user can select table name, column name and then s/he can import data from a csv file. So my question is: how to map this dynamically created table with Hibernate and Java objects?
It can be done dynamically, but it's somewhat messy:
You'll need to dynamically alter Hibernate's Configuration object before SessionFactory is built. If you're using Spring, this can be done by overriding postProcessAnnotationConfiguration() method of AnnotationSessionFactoryBean; otherwise you'll just need to do it using your Configuration object prior to invoking buildSessionFactory() on it.
If you need to do this without application restart, you're looking at either rebuilding your SessionFactory (which means your users will have to wait until that's done) or using a separate SessionFactory instance specifically dedicated to your custom classes (which is next to impossible if your custom classes need to reference your built-in classes).
You can get access to class / table mappings via configuration.getMappings(). You will then need to create a new table mapping via Table API and add it to configuration via addTable(). Same thing will have to be done with PersistentClass which represents a class mapping. If you're using the same class to represent multiple entities (e.g. map multiple tables) make sure to use unique entity names for each. You'll have to do this (alter the configuration) on every app restart.
How much of the tables are dynamically created? Are the tables similar and you just change the database name?
Here is a discussion of changing the table name:
http://www.experts-exchange.com/Programming/Languages/Java/J2EE/Frameworks/Spring/Q_24237099.html
If you are completely building a new table, can you use a view, and just direct people to a view?
Why are you using Hibernate for this, rather than just dynamically creating queries in JDBC?
The database solution - you can create a view and point it to one table or another (assuming the structure is identical).
CREATE VIEW HIBERNATE_NAME
as
SELECT * FROM TABLE_A
or
CREATE VIEW HIBERNATE_NAME
as
SELECT * FROM TABLE_B
You would need you application to execute native SQL (DDL),
however this should be easier than Hibernate hacks

JUnit for database code

I've been trying to implement unit testing and currently have some code that does the following:
query external database, loading
into a feed table
query a view,
which is a delta of my feed and data
tables, updating data table to match
feed table
my unit testing strategy is this:
I have a testing database that I am free to manipulate.
in setUP(), load some data into my testing db
run my code, using my testing db as the source
inspect the data table, checking for counts and the existence/non existence of certain records
clear testing db, loading in a different set of data
run code again
inspect data table again
Obviously I have the data sets that I load into the source db set up such that I know certain records should be added,deleted,updated, etc.
It seems like this is a bit cumbersome and there should be an easier way? any suggestions?
Is it your intent to test the view which generates the deltas, or to test that your code correctly adds, deletes and updates in response to the view?
If you want to test the view, you could use a tool like DBUnit to populate your feed and data tables with various data whose delta you've manually calculated. Then, for each test you would verify that the view returns a matching set.
If you want to test how your code responds to diffs detected by the view, I would try to abstract away database access. I imagine an java method to which you can pass a result set (or list of POJO/DTO's) and returns a list of parameter Object arrays (again, or POJO's) to be added. Other methods would parse the diff list for items to be removed and updated. You could then create a mock result set or pojo's, pass them to your code and verify the correct parameters are returned. All without touching a database.
I think the key is to break your process into parts and test each of those as independently as possible.
DbUnit will meet your needs. One thing to watch out for is that they have switched to using SLF4J as their logging facade instead of JCL. You can configure SLF4J to forward the logging to JCL but be warned if you are using Maven DbUnit sucks in their Nop log provider by default so you will have to use an exclusion, I blogged about this conflict recently.
I use DbUnit, but also I work very hard to not to have to test against the DB.
Tests that go against the database should only exist for the purpose of testing the database interface.
So I have Mock Db Connections that I can set the data for use in all the rest of my tests.
Apart from the already suggested DBUnit, you may want to look into Unitils. It uses DBUnit, but provides more than that (quoting from the site):
Automatic maintenance of databases, with support for incremental,
repeatable and post processing scripts
Automatically disable constraints and set sequences to a minimum value
Support for Oracle, Hsqldb, MySql, DB2, Postgresql, MsSql and Derby
Simplify test database connection setup
Simple insertion of test data with DBUnit * Run tests in a transaction
JPA entity manager creation and injection for hibernate, toplink and *
Hibernate SessionFactory creation and
session
Automatically test the mapping of JPA entities / hibernate mapped
objects with the database
If you are using Maven, one option is to use the sql-maven-plugin. It allows you to run database initialization/population scripts during the maven build cycle.

Categories