I am currently working on an application that uses hibernate as its ORM; however, there is currently no database set up on my machine and I was wanting to start running some tests without one. I figure since hibernate is object/code based that there must be a way to simulate the DB functionality.
If there isn't a way to do it through hibernate, how can this be achieved in the general case (simulation of database)? Obviously, it wont need to handle large amounts of data, just testing functionality.
Just use an embedded DB like Derby
Maybe you could also try to use an ODBC-JDBC bridge and connect to an Excel or Access file, on Windows.
Hibernate is an object-relational mapping tool (ORM). You can't use it without objects and a relational database. Excluding either one makes no sense.
There are plenty of open source, free relational databases to choose from:
MySQL
PostgreSQL
Hypersonic
Derby
MariaDB
SQLite
You're only limited by your ability to download and install one.
Other options are using in-memory database like H2 / hsqldb
I assume you have hidden all the ORM calls behind a clean interface.
If you did, you could simply write another implementation of that interface backed by a Map that caches your objects.
You could then utilize this in your test environment.
But I have to agree with #duffymo, you should just go through the 'first pain' and set up a proper working enviroment.
I'm using H2. One of its major advantages is the use of dialects that simulate the behaviour of the more common DBs. For example - I'm using PostgreSQL and I define the dialect for Hibernate to be PostgreSQL. I'm using it for my integration tests - in each test I create the data that fits my scenario for this test, which is then erased pretty easily. No need to rollback transactions or anything.
Related
I am writing a java application in which I am using Spring Boot and JPA in order to map classes to my database tables.
However, due to a somewhat complex database structure I also have the need of creating custom queries that are not mapped to any specific POJOs / Entities.
Therefore I am using PreparedStatement together with a DataSource with #Autowired annotation.
It hit me that using both of these DB Access methods might not be suitable to use together?
So far everything has worked out in my dev environment, but are there any pitfalls that I should look out for when using both of these together or is there a preferred way of doing custom queries when using JPA?
It should be noted that my database calls are fairly short and happen in a stateless manner, so there should hopefully not be any problems with interfering sessions (?)
JPA EntityManager will not know anything about your changes made with PreparedStatement. This will cause issues with JPA built-in caching, maybe with versioning and also with transaction support.
Though you may need to check this question: Is it OK to use both JPA (for normal CRUDs) and JDBC (for batch update & call stored proc) in the same project
Invan's answer makes a clear point.
On the other hand your fine when:
you need complex queries to SHOW data (read only).
you infrequently need to do some batch updates and do a clear cache entityManager.getEntityManagerFactory().getCache().evictAll()
I'm looking for a simple way to test Hibernate HQL criteria queries. I've tried using IntelliJ's Hibernate Console support, but I've run into problems.
Is there a standalone tool that provides a simple way to test HQL queries? A simple console program that creates the session factory and executes a query passed as an argument would suffice.
You can use the H2 (JDBC in-memory) database, and jetty for your container, to create a container and context that will execute hibernate queries in the unit-test phase of your build (or from JUnit).
Using a console would be my first choice for just playing with HQL (eg Hibernate Tools for eclipse). But if that doesn't work, I would just use JUnit. My team uses that strategy to test the HQL queries that we use in production code, and occasionally to help write queries in the first place.
The test setup involves setting up an in-memory database (we use HSQLDB, but there's others). Insert data either with Hibernate or with raw SQL. Then configure a Hibernate SessionFactory to connect to it, and run your HQL.
We also use this to test other kinds of Hibernate settings or behaviors, and has the side benefit of being a full test suite on Hibernate for our purposes so that we can upgrade and have confidence that nothing we need has changed in an unexpected way.
I doubt it's possible to have such a tool as a separate app, you'll need to specify a hibernate configuration (which might be in Spring Context), and it should be able to find the classes and their HBM files. Moreover you might use different UserTypes or anything like that from other JARs, so I wouldn't even search for it.
For me the best tool is a unit testing framework + debugging facilities of your IDE - you can just stop at some point where you have a session created and do whatever you want in this mode. In IntelliJ for instance, aside of usual expressions, you can put code fragments during debugging which might help you with Criteria API.
Last time I had to do this kind of work I used DbUnit to test my data access layer in which I was using JPA 2.0 with Hibernate
You could try a JUnit approch.
I was learning some JPA to teach to some java friends and I was wondering, how do you handle updates that comes after the creation of the db in JPA? Let's say I have a production environment where there's data that I cannot lose.
Some changes comes in and how do I apply that on my production environment? It there a way that JPA would only update the changes on the database?
Or do I need to manually create a SQL script to update my database?
Is there any other options?
[]'s
Rodrigo Dellacqua
Some changes comes in and how do I apply that on my production environment? It there a way that JPA would only update the changes on the database?
Nothing standardized. In other words, that would be a provider specific feature. For example, Hibernate has a SchemaUpdate tool that can (in theory) safely update a database schema. In practice, many don't use that on a production database (including me).
Or do I need to manually create a SQL script to update my database?
Using migration scripts (and maybe a database migration tool) is IMO the safe way to handle this and is the way to go on real life projects.
And again, some migration tools might provide support for a given JPA provider. For example, liquibase does offer Hibernate support and can diff your Entities against a database to generate a change script.
I have an application where many "unit" tests use a real connection to an Oracle database during their execution.
As you can imagine, these tests take too much time to be executed, as they need to initialize some Spring contexts, and communicate to the Oracle instance. In addition to that, we have to manage complex mechanisms, such as transactions, in order to avoid database modifications after the test execution (even if we use usefull classes from Spring like AbstractAnnotationAwareTransactionalTests).
So my idea is to progressively replace this Oracle test instance by an in-memory database. I will use hsqldb or maybe better h2.
My question is to know what is the best approach to do that. My main concern is related to the construction of the in-memory database structure and insertion of reference data.
Of course, I can extract the database structure from Oracle, using some tools like SQL Developer or TOAD, and then modifying these scripts to adapt them to the hsqldb or h2 language. But I don't think that's the better approach.
In fact, I already did that on another project using hsqldb, but I have written manually all the scripts to create tables. Fortunately, I had only few tables to create. My main problem during this step was to "translate" the Oracle scripts used to create tables into the hsqldb language.
For example, a table created in Oracle using the following sql command:
CREATE TABLE FOOBAR (
SOME_ID NUMBER,
SOME_DATE DATE, -- Add primary key constraint
SOME_STATUS NUMBER,
SOME_FLAG NUMBER(1) DEFAULT 0 NOT NULL);
needed to be "translated" for hsqldb to:
CREATE TABLE FOOBAR (
SOME_ID NUMERIC,
SOME_DATE TIMESTAMP PRIMARY KEY,
SOME_STATUS NUMERIC,
SOME_FLAG INTEGER DEFAULT 0 NOT NULL);
In my current project, there are too many tables to do that manually...
So my questions:
What are the advices you can give me to achieve that?
Does h2 or hsqldb provide some tools to generate their scripts from an Oracle connection?
Technical information
Java 1.6, Spring 2.5, Oracle 10.g, Maven 2
Edit
Some information regarding my unit tests:
In the application where I used hsqldb, I had the following tests:
- Some "basic" unit tests, which have nothing to do with DB.
- For DAO testing, I used hsqldb to execute database manipulations, such as CRUD.
- Then, on the service layer, I used Mockito to mock my DAO objects, in order to focus on the service test and not the whole applications (i.e. service + dao + DB).
In my current application, we have the worst scenario: The DAO layer tests need an Oracle connection to be run. The services layer does not use (yet) any mock objects to simulate the DAO. So services tests also need an Oracle connection.
I am aware that mocks and in-memory database are two separates points, and I will address them as soon as possible. However, my first step is to try to remove the Oracle connection by an in-memory database, and then I will use my Mockito knowledges to enhance the tests.
Note that I also want to separate unit tests from integration tests. The latter will need an access to the Oracle database, to execute "real" tests, but my main concern (and this is the purpose of this question) is that almost all of my unit tests are not run in isolation today.
Use an in-memory / Java database for testing. This will ensure the tests are closer to the real world than if you try to 'abstract away' the database in your test. Probably such tests are also easier to write and maintain. On the other hand, what you probably do want to 'abstract away' in your tests is the UI, because UI testing is usually hard to automate.
The Oracle syntax you posted works well with the H2 database (I just tested it), so it seems H2 supports the Oracle syntax better than HSQLDB. Disclaimer: I'm one of the authors of H2. If something doesn't work, please post it on the H2 mailing list.
You should anyway have the DDL statements for the database in your version control system. You can use those scripts for testing as well. Possibly you also need to support multiple schema versions - in that case you could write version update scripts (alter table...). With a Java database you can test those as well.
By the way, you don't necessarily need to use the in-memory mode when using H2 or HSQLDB. Both databases are fast even if you persist the data. And they are easy to install (just a jar file) and need much less memory than Oracle.
Latest HSQLDB 2.0.1 supports ORACLE syntax for DUAL, ROWNUM, NEXTVAL and CURRVAL via a syntax compatibility flag, sql.syntax_ora=true. In the same manner, concatenation of a string with a NULL string and restrictions on NULL in UNIQUE constraints are handled with other flags. Most ORACLE functions such as TO_CHAR, TO_DATE, NVL etc. are already built in.
At the moment, to use simple ORACLE types such as NUMBER, you can use a type definition:
CREATE TYPE NUMBER AS NUMERIC
The next snapshot will allow NUMBER(N) and other aspects of ORACLE type compatibility when the flag is set.
Download from http://hsqldb.org/support/
[Update:] The snapshot issued on Oct 4 translates most Oracle specific types to ANSI SQL types. HSQLDB 2.0 also supports the ANSI SQL INTERVAL type and date / timestamp arithmetic the same way as Oracle.
What are your unit tests for?
If they test the proper working of DDLs and stored procedures then you should write the tests "closer" to Oracle: either without Java code or without Spring and other nice web interfaces at all focusing on the db.
If you want to test the application logic implemented in Java and Spring then you may use mock objects/database connection to make your tests independent of the database.
If you want to test the working as a whole (what is against the modular development and testing principle) then you may virtualize your database and test on that instance without having the risk of doing some nasty irreversible modifications.
As long as your tests clean up after themselves (as you already seem to know how to set up), there's nothing wrong with running tests against a real database instance. In fact it's the approach I usually prefer, because you'll be testing something as close to production as possible.
The incompatibilities seem small, but really end up biting back not so long afterwards. In a good case, you may get away with some nasty sql translation / extensive mockery. In bad cases, parts of the system will be just impossible to test, which I think is an unacceptable risk for business-critical systems.
My integration tests would run much faster if I used in-memory-database instead of PostgreSQL. I use JPA (Hibernate) and I need an in-memory-database that would be easy to switch to using JPA, easy to setup, and reliable. It needs to support JPA and Hibernate (or vice verse if you will) rather extensively since I have no desire to adopt my data access code for tests.
What database is the best choice given requirements above?
For integration testing, I now use H2 (from the original author of HSQLDB) that I prefer over HSQLDB. It is faster (and I want my tests to be as fast as possible), it has some nice features like the compatibility mode, the dev team is very responsive (while HSQLDB remained dormant for years until very recently).
I've been using HSQLDB in-memory for integration testing JPA/Hibernate persistence in Java. Starts pretty quickly, doesn't require any special setup.
The only issue I've seen so far with using HSQLDB with Hibernate was to do with batch size needing to be set to 0, but that might just have been related to an old version. I'll have a dig and see if I can find details of that problem.
Derby supports an in-memory mode these days, it is no longer marked experimental.
I use Derby. For one thing it is about 3 less lines of code per unit test since there is no need for a shutdown after the test. However, you need to use a JPA implementation that can drop and create tables such as EclipseLink.
Derby can also initialize a new in-memory database from a file so you can have a reference database and revert to it at anytime.
For unit testing though, I prefer to create my objects in my unit test's #Before logic I find it easier especially with JPA as it allows me the flexibility to do refactorings and not have to worry about the underlying database structure, other tools such as DBunit rely on practically a static structure and refactoring implies changing of the DBunit XMLs manually rather than relying on Eclipse's refactoring capabilities.