We have a (possibly large) custom data structure implemented in Java (8+). It has a simple and optimal API for querying pieces of data. The logical structure is roughly similar to an RDMS (it has e. g. relations, columns, primary keys, and foreign keys), but there is no SQL driver.
The main goal is to access the data via ORM (mapping logical entities to JPA annotated beans). It would be nice if we could use JPQL. Hibernate is preferred but other alternatives are welcome too.
What is the simplest way to achieve this? Which are the key parts of such an implementation?
(P. S. Directly implementing SessionImplementor, EntityManagerImplementor etc. seems to be too complicated.)
You have two possibilities.
Implement a JDBC compliant driver for your system, so you can use a JPA implementation such as Hibernate "directly" (although you may need to create a custom dialect for your system).
Program directly against the JPA specification like ObjectDB does, which bypasses the need to go through SQL and JPA implementations completely.
The latter one is probably easier, but you'd still need to implement the full JPA API. If it's a custom in-house-only system, there's very little sense in doing either one.
One idea I thought up just now, that I feel may work is this:
Use an existing database implementation like H2 and use the JPA integration with that. H2 already has a JPA integration libraries, so it should be easy.
In this database, create a Java stored procedure or function and call it from your current application through JPA. See this H2 documentation on how to create a Java stored procedure or function. (You may want to explore the section "Using a Function as a Table" also.)
Define a protocol for the service methods and encapsulate it in a model class. An instance of this model class may be passed to the function/SP and responses retrieved.
Caveat: I have never done this myself but I think it will work.
Edit: Here is a diagram representing the thought. Though the diagram show H2 separately, it will most probably be in the same JVM as "Your Java/JEE application". However, since it is not necessary to use H2, I have shown it as as separate entity.
I have generated the representations for my database-model in jooq.
Can I use this to recreate the Database?.
createTable(org.jooq.Table<?> table) wants me to specify the columns.
Ideally when the schema changes, i would just update the jooq representation and when another user installs it it would automatically create the right schema.
There is a pending feature request for this kind of functionality:
https://github.com/jOOQ/jOOQ/issues/3160
But as of jOOQ 3.7, this isn't yet possible. The main challenge is the fact that the generated schema meta information will always lack important pieces (e.g. vendor-specific storage clauses), so this kind of functionality is good for simple databases or test databases at best.
Does exists a java library that can create sql statements?
I'm not in search of something fancy, just something at "string manipulation" level: I just use jdbc (with Preparestatements and Resultsets) but I don't really like to pass huge strings containing SQL code...
What I need is a "simple" Select class (or something similar); in my mind all I really want is to be able to do
SQLStatement stat = Select("*").from("table").where("condition and condition").orderby("something");
ResultSet rs = Connection.getResultSet(stat.toString());
/* equals to "select * from table where condition and condition order by something" */
Maybe I'm blind, but I cannot find something like that...
Obviously, I want some methods/class able to write inserts and updates and the other stuff...
I excluded ORMs for two reasons:
the db schema it's "old" and I cannot change it, and I'm not sure how can I adapt the ORM to follow our db
AFAIK the ORMs needs to change the model (maybe adding a base class, maybe you need to implements an interface) and the model in my project is big, old and grumpy
Onestly, I don't really like ORMs: Objects and Set theory just aren't made to be mapped (IMHO)
ORM (Object Relational Mapping) library is the clue.
Hibernate is the most mature one.
And the Hibernate-s Criteria API is object - oriented way to create such queries as You wished. Criteria API doc.
Hibernate is most likely what you're looking for. It contains many advanced features, but SQL statements are more straightforward.
Take a look at their site: http://www.hibernate.org/
I'd also recommend skimming through this guide:
https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
Try SQLBuilder project. Honestly, I have not used this. Looking at their docs, i think it might suit your requirement.
You can also try to find similar APIs in Sourceforge,Google code etc..
I am not sure if you use Java for a native application or for the web.
If you use Java for web you could consider using the Play framework.
Easy and has Hibernate included with a really simple implementation (easier when implementing Hibernate yourself).
In my current project (an order management system build from scratch), we are handling orders in the form of XML objects which are saved in a relational database.
I would outline the requirements like this:
Selecting various details from anywhere in the order
Updating / enriching data (e.g. from the CRM system)
Keeping a record of the changes (invalidating old data, inserting new values)
Details of orders should be easily selectable by SQL queries (for 2nd level support)
What we did:
The serialization is done with proprietary code, disassembling the order into tables like customer, address, phone_number, order_position etc.
Whenever an order is processed a bit further (e.g. due to an incoming event), it is read completely from the database and assembled back into a XML document.
Selection of data is done by XPath (scattered over code).
Most updates are done directly in the database (the order will then be reloaded for the next step).
The problems we face:
The order structure (XSD) evolves with every release. Therefore XPaths and the custom persistence often breaks and produces bugs.
We ended up having a mixture of working with the document and the database (because the persistence layer can not persist the changes in the document).
Performance is not really an issue (yet), since it is an offline system and orders are often intentionally delayed by days.
I do not expect free consultancy here, but I am a little confused on how the approach could be improved (next time, basically).
What would you think is a good solution for handling these requirements?
Would working with an object graph, something like JXPath and OGNL and an OR mapper be a better approach? Or using XML support of e.g. the Oracle database?
If your schema changes often, I would advise against using any kind of object-mapping. You'd keep changing boilerplate code just for the heck of it.
Instead, use the declarative schema definition to validate data changes and access.
Consider an order as a single datum, expressed as an XML document.
Use a document-oriented store like MongoDB, Cassandra or one of the many XML databases to manipulate the document directly. Don't bother with cutting it into pieces to store it in a relational db.
Making the data accessible via reporting tools in a relational database might be considered secondary. A simple map-reduce job on a MongoDB, for example, could populate the required order details into a relational database whenever required, separating the two use cases quite naturally.
The standard Java EE approach is to represent your data as POJOs and use JPA for the database access and JAXB to convert the objects to/from XML.
JPA
Object-to-Relational standard
Supported by all the application server vendors.
Multiple available implementations EclipseLink, Hibernate, etc.
Powerful query language JPQL (that is very similar to SQL)
Handles query optimization for you.
JAXB
Object-to-XML standard
Supported by all the application server vendors.
Multiple implementations available: EclipseLink MOXy, Metro, Apache JaxMe, etc.
Example
http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-15.html
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
It's a pretty open ended question. I'll be starting out a new project and am looking at different ORMs to integrate with database access.
Do you have any favorites?
Are there any you would advise staying clear of?
I have stopped using ORMs.
The reason is not any great flaw in the concept. Hibernate works well. Instead, I have found that queries have low overhead and I can fit lots of complex logic into large SQL queries, and shift a lot of my processing into the database.
So consider just using the JDBC package.
None, because having an ORM takes too much control away with small benefits. The time savings gained are easily blown away when you have to debug abnormalities resulting from the use of the ORM. Furthermore, ORMs discourage developers from learning SQL and how relational databases work and using this for their benefit.
Many ORM's are great, you need to know why you want to add abstraction on top of JDBC. I can recommend http://www.jooq.org to you (disclaimer: I'm the creator of jOOQ, so this answer is biased). jOOQ embraces the following paradigm:
SQL is a good thing. Many things can be expressed quite nicely in SQL. There is no need for complete abstraction of SQL.
The relational data model is a good thing. It has proven the best data model for the last 40 years. There is no need for XML databases or truly object oriented data models. Instead, your company runs several instances of Oracle, MySQL, MSSQL, DB2 or any other RDBMS.
SQL has a structure and syntax. It should not be expressed using "low-level" String concatenation in JDBC - or "high-level" String concatenation in HQL - both of which are prone to hold syntax errors.
Variable binding tends to be very complex when dealing with major queries. THAT is something that should be abstracted.
POJO's are great when writing Java code manipulating database data.
POJO's are a pain to write and maintain manually. Code generation is the way to go. You will have compile-safe queries including datatype-safety.
The database comes first. While the application on top of your database may change over time, the database itself is probably going to last longer.
Yes, you do have stored procedures and user defined types (UDT's) in your legacy database. Your database-tool should support that.
There are many other good ORM's. Especially Hibernate or iBATIS have a great community. But if you're looking for an intuitive, simple one, I'll say give jOOQ a try. You'll love it! :-)
Check out this example SQL:
// Select authors with books that are sold out
SELECT *
FROM T_AUTHOR a
WHERE EXISTS (SELECT 1
FROM T_BOOK
WHERE T_BOOK.STATUS = 'SOLD OUT'
AND T_BOOK.AUTHOR_ID = a.ID);
And how it can be expressed in jOOQ:
// Alias the author table
TAuthor a = T_AUTHOR.as("a");
// Use the aliased table in the select statement
create.selectFrom(a)
.whereExists(create.selectOne()
.from(T_BOOK)
.where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
.and(T_BOOK.AUTHOR_ID.equal(a.ID))))));
Hibernate, because it's basically the defacto standard in Java and was one of the driving forces in the creation of the JPA. It's got excellent support in Spring, and almost every Java framework supports it. Finally, GORM is a really cool wrapper around it doing dynamic finders and so on using Groovy.
It's even been ported to .NET (NHibernate) so you can use it there too.
Hibernate, because it:
is stable - being around for so many years, it lacks any major problems
dictates the standards in the ORM field
implements the standard (JPA), in addition to dictating it.
has tons of information about it on the Internet. There are many tutorials, common problem solutions, etc
is powerful - you can translate a very complex object model into a relational model.
it has support for any major and medium RDBMS
is easy to work with, once you learn it well
A few points on why (and when) to use ORM:
you work with objects in your system (if your system has been designed well). Even if using JDBC, you will end up making some translation layer, so that you transfer your data to your objects. But my bets are that hibernate is better at translation than any custom-made solution.
it doesn't deprive you of control. You can control things in very small details, and if the API doesn't have some remote feature - execute a native query and you have it.
any medium-sized or bigger system can't afford having one ton of queries (be it at one place or scattered across), if it aims to be maintainable
if performance isn't critical. Hibernate adds performance overhead, which in some cases can't be ignored.
I would recommend using MyBatis. It is a thin layer on top of JDBC, it is very easy to map objects to tables and still use plain SQL, everything is under your control.
I had a really good experience with Avaje Ebean when I was writing a medium sized JavaSE application.
It uses standard JPA annotations to define entities, but exposes a much simpler API (No EntityManager or any of that attached/detached entities crap). It also lets you easily use SQL queries or event plain JDBC calls when necessary.
It also has a very nice fluid and type-safe API for queries. You can write things like:
List<Person> boys = Ebean.find(Person.class)
.where()
.eq("gender", "M")
.le("age", 18)
.orderBy("firstName")
.findList();
SimpleORM, because it is straight-forward and no-magic. It defines all meta data structures in Java code and is very flexible.
SimpleORM provides similar
functionality to Hibernate by mapping
data in a relational database to Java
objects in memory. Queries can be
specified in terms of Java objects,
object identity is aligned with
database keys, relationships between
objects are maintained and modified
objects are automatically flushed to
the database with optimistic locks.
But unlike Hibernate, SimpleORM uses a
very simple object structure and
architecture that avoids the need for
complex parsing, byte code processing
etc. SimpleORM is small and
transparent, packaged in two jars of
just 79K and 52K in size, with only
one small and optional dependency
(Slf4j). (Hibernate is over 2400K
plus about 2000K of dependent Jars.)
This makes SimpleORM easy to
understand and so greatly reduces
technical risk.
Eclipse Link, for many reasons, but notably I feel like it has less bloat than other main stream solutions (at least less in-your-face bloat).
Oh and Eclipse Link has been chosen to be the reference implementation for JPA 2.0
While I share the concerns regarding Java replacements for free-form SQL queries, I really do think people criticizing ORM are doing so because of a generally poor application design.
True OOD is driven by classes and relationships, and ORM gives you consistent mapping of different relationship types and objects.
If you use an ORM tool and end up coding query expressions in whatever query language the ORM framework supports (including, but not limited to Java expression trees, query methods, OQL etc.), you are definitely doing something wrong, i.e. your class model most likely doesn't support your requirements in the way it should. A clean application design doesn't really need queries on the application level. I've been refactoring many projects people started out using an ORM framework in the same way as they were used to embed SQL string constants in their code, and in the end everyone was suprised about how simple and maintainable the whole application gets once you match up your class model with the usage model. Granted, for things like search functionality etc. you need a query language, but even then queries are so much constrained that creating an even complex VIEW and mapping that to a read-only persistent class is much nicer to maintain and look at than building expressions in some query language in the code of your application. The VIEW approach also leverages database capabilities and, via materialization, can be much better performance-wise than any hand-written SQL in your Java source.
So, I don't see any reason for a non-trivial application NOT to use ORM.