Hibernate Tools and the ever changing database - java

I am currently using Hibernate Tools 3.1; I customized naming convention and DAO templates. The database (SQL Server 2005) in early development phase and I'm in charge of rebuilding the mappings, entities, DAOs, configuration, whatever. Each time I have to reverse-engineer the tables and so I lose every customization I made on the mappings (*.hbm.xml files) like adjusting the identity columns, picking the fields used in equals and toString. I was considering to write the diff XML in a file and the "merge" that onto the generated mapping (see my related question) but I was wondering... is there any best practice/tool for dealing with these annoying, unavoidable, critical tasks?

I'd strongly recommend against continual reverse engineering. Reverse engineering is a great one time thing, but changes need to be managed as changes to both the hbm and the database.
We use migrations to manage db changes, and we include the associated changes in the hbm. If Hibernate has it (I believe it does) you may want to look into annotations instead of an hbm, they can be quite a bit easier to maintain.

This is two and a half years late, but I'll offer a dissenting opinion. You should be able to make any customizations you need to the mapping files through the hibernate.reveng.xml file or a custom ReverseEngineeringStrategy. For the classes themselves, you should always generate to base classes and extend them with classes containing custom code.
For example, generate com.company.vo.generated.CustomerGenerated and extend it with com.company.vo.custom.Customer. Code generation should overwrite all classes in the generated package but never in the custom package (although you can have Hibernate Tools generate these custom classes in the target directory so that you can copy and paste blanks into the custom directory as needed). This way you can override methods for equals, toString, etc in the custom classes and not lose your changes when you regenerate. Also note that the best practice is to not check in generated code into SCM.
There are some great examples on this site of how to achieve this using Maven, the Hibernate3 plugin, and the build helper plugin. Most of these have very helpful answers by Pascal Thivent. This method is working beautifully for me, and while there is a bit of a learning curve it's a wonderful thing to be able to propagate database changes to the app with a single Maven command.

Related

Down-sizing/custom jOOQ build?

I have a database-heavy distributable java application that's currently only 400k. We need improved database query building as well as support for a few specific database dialects.
jOOQ has to be shaded into our JAR and it balloons it up to 1.6MB, even when using the minimizeJar elements for shade.
Is there a way I can do a custom build or strip out the components of jOOQ that we have no use for right now? Dialects, non insert/select/delete query classes, other features we don't need?
I thought about trying to identify every imported class that we're using and setting maven to only shade those, but I'd also need to handle classes jOOQ uses internally and I don't know how reliant jOOQ is on everything.
If I could strip it down to a few hundred k, I'd be sold on continuing to use it.
jOOQ is a domain-specific language implemented according to the principles explained here:
http://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/
This means that every "production" or "primary" from the DSL specification generates a Java interface with all the overhead this may generate in the class loader. Additionally, since jOOQ 3.0, record and row types with degree 1-22 were introduced (e.g. org.jooq.Row1, org.jooq.Row2, ... org.jooq.Row22). All of these elements are part of the API, which probably cannot be stripped down any further.
Of course, you can try to manually strip down the jOOQ API and implementation, removing all the row types from it. Another entire statement that you might not need is the MERGE statement, which also has an extensive API. Then, there are the tools packages, which aren't strictly needed, specifically:
org.jooq.tools.csv
org.jooq.tools.json
org.jooq.types
org.jooq.util.[dialect]
Also, you can try to remove a couple of classes from the org.jooq.impl package. The class names should be fairly straight-forward to help you decide whether something is needed.
It would be interesting to see how far you get with such measures. This might be useful for Android users, too.

Hibernate 4: How to dynamically manage tables in a db

This questions has been asked a few times, but most of the answers are a few years old so I'll post this hoping someone has figured out an answer.
Problem: We have a production live system that is currently working great with hibernate 4/jboss/etc. The problem is a few of our production sites are integrated with legacy systems that are using the same database, and creating data in new tables.
We've been given a requirement to action against these tables from our system. Unfortunately, the way these legacy systems work, I can't define a default entity type to match against these tables, and the table names/columns vary widely.
What I can do is find the name of the tables.
What I can't do is get hibernate to manage these tables like I want to. I've spent the last week looking for a solution, but the biggest problem I have is that the entity manager is immutable after instantiated.
Older stackoverflow questions:
Adding Tables and Columns in Hibernate on The Fly?
Has anyone have any hints on where I can possibly make this requirement achievable?
Thanks in advance.
Here's an outline of a way that this could work. Basically, you'd use Hibernate's reverse engineering tools to generate class files, then compile them on the fly, and then create a new Configuration with them and use that to generate a new EntityManager.
Hibernate reverse engineering
There's a set of IDE and Ant tools that Hibernate provides for reverse engineering and code generation which, among other thing, can generate code based on a database definition. Generally, their expectation is that people are going to generate code/mapping files based on a database either once, or during the build. What you want to do is generate those artifacts from your running program, which is definitely off-label usage. I'd start with the Ant task. End goal of this step is to have generated POJOs representing the contents of the tables in your database.
In process compilation
Now that you've got your Java files, you need to compile them. See this question for an example of using Process to run javac on your files. If you compile them to your classpath, they'll be available to your process.
Build a new configuration
Using the ejb3=true flag when you generated the POJOs, you should know be able to add them to a Configuration object already annotated. I'm not sure what the best way will be for you to actually identify the newly generated classes so that you can .addAnnotatedClass(). It may be best to capture output from the hbm2java, or perhaps to scan the output folder for the new Java files, or perhaps there's another way that your program can 'know' about the new entities. In any case, you can then use that Configuration to create a new EntityManager that maps to your new database structures.

Difference between Hibernate mapping file and annotation

Today I was trying to create a application using Hibernate as ORM. So while creating I had a doubt. What is the best practice to use, Hibernate mapping file (.hbm file) or annotations ? What are the pros and cons of it ? Please help me in understanding.
there is no functional difference. You can do (almost) the same things with both approaches
xml files were used before Java had annotations (added in 1.5), so they can be considered an outdated way of mapping
it is generally preferred to use JPA annotations rather than hibernate-specific ones; if using xml - there is a JPA xml format, which should be preferred to hibernate native one
The question is what is your taste - both ways can do (mostly) the same, the difference is how to write.
With annotations you have the Java member variable/getter and the mapping directly together at one place.
Xml mapping files give a better overview over the table and its mapping.
In my opinion xml mapping files help for a better design of the database and application. Annonations tend to force the direction Java class -> mapping -> database table, which is the wrong direction (the database always should be designed first - changing database tables later is a lot of effort - most performance leaks are in a bad database design - Java classes easily can be changed any time).
There if one functional advantage of xml files: If you have different databases with structural differences, for example one Oracle database and one MySQL database, perhaps some differences in table names and data types, then for porting your application from one database to another you only need to write some new mapping files. You do not need to change a single line of Java code. This is not possible with annotations.
I prefer to use xml mapping files. That is my taste.
One good use-case for using the XML approach is if you are persisting objects that have been generated by another utility and therefore cannot be annotated.
Other than that, I would use annotations as it tends to lend itself to a cleaner implementation and you're less likely to introduce bugs by misspelling property names.
This is how it says in "TUTORIALS POINT"
"If you going to make your application portable to other EJB 3 compliant ORM applications, you must use annotations to represent the mapping information but still if you want greater flexibility then you should go with XML-based mappings"
For me I would prefer XML configuration file, than annotation. Because then we can do changes, with minimum code changes.
Annotations are based on the principle of convention over configuration:
http://en.wikipedia.org/wiki/Convention_over_configuration
while xml files are just configuration.
There are many discussions about using annotations vs using configuration.
stackoverflow link
From my point of view, I prefer annotations because it is easier to write and to maintain.
Annotations are developed with java language and java developer easy to learn when compared with XML. And one more point in real time table names and column names are fixed 99%, so no need to change java code also
but if you want to change table names and column names frequently you will move with XML
finally cfg.xml file is manadatary because database may change.

Is it possible to generate JPA entity classes from a database schema at runtime?

IDEs like Netbeans allow generation of entity classes through a persistence context. If you had access to underlying generation method (not sure if it is an external tool or part of the IDE), could you generate database entity classes dynamically at runtime? The idea being that you could hook into the entity classes using reflection.
I know you can go the other way and generate the database from the entity class, however due to permissions issues in my work environment that would be a no go. However, if you reverse the process and pull the classes from the database it may be feasible in my environment. The idea being that the database would serve as a single point of configuration/control.
It's theoretically possible but what would be the point? Java is statically typed so you would only be able to use the generated classes by reflection and you would have no way of giving them behaviour, so removing the whole point of object-relational mapping. Loading the data into Maps or just using SQL record sets would be more convenient.
If you have an existing schema you can write classes that act in the way your application needs and declaratively map them onto the schema. That way the code is the simplest expression of your application logic and is persistence-agnostic.
You can find on JBoss website a tool to do the reverse engineering from database to java objects.
The source code is available, you should dig in!
https://www.jboss.org/tools/download/stable.html
Assuming you're using Hibernate, you might be able to use Hibernate Tools to generate the database schema. Although primarily designed for Eclipse and Ant, its theoretically possible to link it in and invoke it like any other JAR.

Maintainability of Java annotations?

My project is slowly implementing Java annotations. Half of the developers - myself included - find that doing anything complex with annotations seems to add to our overall maintenance burden. The other half of the team thinks they're the bee's knees.
What's your real-world experience with teams of developers being able to maintain annotated code?
My personal experience is that, on average, dealing with annotations is far easier for most developers than dealing with your standard Java XML Configuration hell. For things like JPA and Spring testing they are absolute life-savers.
The good thing about annotations is that they make configuration on your classes self-documenting. Now, instead of having to search through a huge XML file to try and figure out how a framework is using your class, your class tells you.
Usually the issue with changes like this is that getting used to them simply takes time. Most people, including developers, resist change. I remember when I started working with Spring. For the first few weeks I wondered why anyone would put up with the headaches associated with it. Then, a few weeks later, I wondered how I'd ever lived without it.
I feel it breaks into two uses of annotations - annotations to provide a 'description' of a class vs. annotations to provide a 'dependency' of the class.
I'm fine with a 'description' use of annotations on the class - that's something that belongs on the class and the annotation helps to make a shorthand version of that - JPA annotations fall under this.
However, I don't really like the 'dependency' annotations - if you're putting the dependency directly on the class - even if it's determined at runtime from an annotation rather than at compile time in the class - isn't that breaking dependency injection? (perhaps in spirit rather than in rule...)
It may be personal preference, but I like the one big XML file that contains all the dependency information of my application - I view this as 'application configuration' rather than 'class configuration'. I'd rather search through the one known location than searching through all the classes in the app.
It depends highly on IDE support. I feel that annotations should be kept in sync with the code via checks in the IDE, but that support for this is somewhat lacking.
E.g. the older version of IDEA would warn if you overrode a function without #Override, but wouldn't remove the #Override tag if you changed the method signature (or the superclass signature, for that matter) and broke the relation.
Without support I find them a cumbersome way to add metadata to code.
I absolutely love annotations. I use them from Hibernate/JPA, Seam, JAXB....anything that I can. IMO there's nothing worse than having to open up an XML file just to find out how a class is handled.
To my eye annotations allow a class to speak for itself. Also annotations are (hopefully) part of your IDEs content assist, whereas with XML config you are usually on your own.
However, it may come down to how the XML configs and Annotations are actually used by any particular library (as most offer both), and what sort of annotation is used. I can imagine that annotations that define something that is build-specific (eg. file/url paths) may actually be easier as XML config.
i personally feel that the the specific use case you mentioned (auto-generate web forms) is a great use case for annotations. any sort of "framework" scenario where you can write simplified code and let the framework do the heavy (often repetitive) lifting based on a few suggestions (aka annotations) is, i think, the ideal use case for annotations.
i'm curious why you don't like annotations in this situation, and what you consider to be the "maintenance burden"? (and, i'm not trying to insult your position, just understand it).

Categories