I have classes that are named exactly the same across different plug-ins that I use for my application, and I'd like to be able to configure them properly with Hibernate. The problem is that it looks like Hibernate dynamically generates a class' package name when trying to find a class when it's doing its mapping. With one plug-in this scheme works, but across multiple plug-ins it's not working. It looks like Hibernate gets confused when dealing with Hibernate configuration files across multiple plug-ins.
Is this because each plug-in has its own class-loader? What is the best way to proceed to make this work with the existing plug-ins and Hibernate?
The problem is, that every plugin has its own Classloader and Hibernate uses Reflection to find the right classes.
I have a very nice article at home about exactly this problem, but this one is in German. I will try to explain what you need to do.
In order to have the datastructure shared over several plugins, you have to put it in a plugin and enable a feature called buddy-policy.
Lets say you have a main-application-plugin which is initiating hibernate on startup, this plugin needs to "see" the classes from the datastructure-plugin. To do this the main-plugin sets its Buddy-Policy to "registered" and the datastructure-plugin registers itself as a "buddy". Unfortunately you have to do this all directly in the manifest file, at least in 3.3 there was no way to do this in the editor.
Once this buddy-policy works, Hibernate will also.
I looked up my old application and here is how I did it.
The main-application (toolseye.rcp) is dependent on the hibernate plugin (de.eye4eye.hibernate) and the datastructure-plugin (toolseye.datastructures)
The hibernate-plugin specifies its buddy-policy as "registered"
The datastructure-plugin registers itself to the hibernate-plugin
Here are the important lines:
Hibernate-plugin de.eye4eye.hibernate
Eclipse-BuddyPolicy: registered
Datastructure-plugin toolseye.datastructures
Eclipse-RegisterBuddy: de.eye4eye.hibernate
Put those line directly in the MANIFEST.MF
Both plugins need to reexport their packages in order that the main application or whatever layer you have in between can use them.
Hope that helped.
Just to make this complete.
Instead of using Hibernate, EclipseLink could be used as JPA-provider in a Eclipse RCP application. EclipseLink is the former TopLink from Oracle and has been choosen to be the reference implementation for JPA 2.
The point for an RCP is, that EclipseLink is available as OSGI-Bundles (org.eclipse.persistence.jpa), and due to that it can load classes from another plugin without an additional buddy-policy.
Currently I was playing around, using the following project structure (Model-View-Presenter Pattern). The names in the brackets specify the dependecy plugins (not all are included, only the ones related to this question)
rcp.mvp.view (rcp.mvp.presenter /
rcp.mvp.model)
rcp.mvp.presenter (rcp.mvp.data -
data reexports the model, so this is
not needed here) *
rcp.mvp.data (rcp.mvp.data.mysql /
rcp.mvp.model / javax.persistence /
org.eclipse.persistence.jpa)
rcp.mvp.data.mysql - provides only
the mysql-jdbc-driver. has to be
inside the classpath
rcp.mvp.model
In this scenario, the JPA provider in the data-plugin is able to load the classes from the model-plugin without a buddy-policy.
*Note, the presenter is not dependent on any JPA packages since this is encapsulated by DAOs (the main reason why to use them still)
Links
User Guide
RCP example (unfortunately not using DAOs)
EclipseLink conceptual Webinar from live.eclipse.org
Related
I have two Java projects with same domain objects.First project is the administration of a webapp. And second project is the webapp.
I've chosen this approach in order to allow deployment of administration without downtime for my webapp.
So both projects use same database. I'm using spring-data and marking entities with #Entity.
My question is: is there any way to replicate domain objects in each project?
For example creating another maven module with the domain objects and mark as a dependency. (But in this case #Entity will still work?).
the way is just as you said it - create a maven module (usually called datamodel, infomodel or something along those lines) that contains all of your JPA classes (#Entity classes).
this model can either be a completely separate 3rd project (more work) or, more likely, pick one of the 2 projects as the "owner" of the module and the other project will simply list it as a dependency. in both cases you'll need to think about things like version compatibility (what happens when you update administration but not the webapp and the entities changed? who updates the database, how do you make sure the older code can still read/write it?)
as for working, JPA classes work just fine in their own jar.
Like you have raised is a good approximation, separating two different maven projects.
What you're trying to do is very similar to the structure of Broadleaf Commerce. It is a multi-module project using Maven and Spring, is open source, so you can look at how it is structured to see if it helps.
Here you have another guide of how to implement it step by step. Hope it helps.
It seams that you will need at least three modules.
1st - the domain module with the enitity annotated domain classes;
2nd - the application itself witch depends on the domain module;
3rd - the adm module witch also depends on the domain.
Now that you have a multi-module maven project you should have a 4th project formally listing the other three as its child modules.
P.s.: Resist to the temptation of creating separate git repositories and evolving the versions of the modules separately.(just an advice)
While working on a modular system architecture for an enterprise application I run into some problems with database initialization. We have a core library that provides base entities and base configuration. On top of this core several modules are build. They are pluggable and can have their own entities and configuration. Some characteristics:
Configuration, like system properties, resourcebundles, etc, are all stored in the database.
JPA is used to make the system database independent.
System runs on Java SE
Every module can bring its own tables, but they can also require to populate the core property table, or the core resourcebundle table. So somehow we need some mechanisme to run a DDL and DML initialization for the database. Some options:
Create simple sql scripts. Disadvantage is that they must be database independent and perhaps this is not the most developer friendly. Unless we can generate them with some DB diff tool?
Use Java classes to initialize via JPQL?
Store configuration in files? This avoids a lot (but not all) of configuration DML.
Use some tool like liquibase?
What would be the best practice for this (or a similar) problem?
Use a database for store all configuration data is the best option. Many products, such as WebSphere Portal or Liferay use a database to store the configuration data for each portlet or even for theme. Don't forget to include those that are used as part of an SOA and Business Rules.
Therefore, the use of SQL scripts is also the best choice. However, if you require very specific features of SQL, you may need to create several versions of same script for each database management system.
I am currently in an project that has the same idea of modules that add functionality to a core system.
Generally we are using maven and multiple src folders as well as maven profiles and different builds to be able to generate a deployable with different modules. (we do not have the necessity to push out single modules and install them later on - this might be different in your project. We just build different versions with different modules.)
Anyway, for the DB we are using liquibase. Firstly to manage the DB and the changes done to it. But also (and this might be helpful to you) to include/generate another SQL script that adds tables for the modules.
Each module has its own changeset-file that includes everything that is necessary for that module (also in different versions as the modules evolve through time). These can then be applied or not.
So, I think liquibase could also be useful in your case (even though it's main purpose is to manage DB changes).
I have a large scale project I am working on at the moment using Eclipse. Normally, as a one man team, these problems would not be an issue, but as our team is not one person we need to be able to break up pieces of the project to be worked on by certain team members.
In simplicity, let's say I have two layers to be separated apart:
1. Each DAO is a separate Java project, to be worked upon individually
2. The web-tier service layer contains all of our service endpoints and must be able to reference all of the DAOs. This layer runs on Tomcat as a dynamic web project, and utilizes Adobe LiveCycle Data Services as the piece that handles creation and management of endpoints.
Now, the issue we are running into is that when we create a DAO and unit test it individually it runs great. But when we reference it into our service project and try to run it we begin to get all kinds of issues related to the fact that we have two different versions of certain jars referenced in and as such we begin to have errors when running the server.
As a result, we know we can solve the issue by pulling the problem jars and ensuring that this is not an issue again in the future, but as I said before this is a large scale project with multiple people working on it and we don't want to be spending our time weeding out dependency issues when under the gun.
We are looking for recommendations on where to proceed for alternative solutions? Our team is new to JavaEE and as such we don't have much of a bearing on what we can use to tie everything together in it, or if it is a viable solution. Should we be looking at turning our DAOs into EJBs and deploying them in an EAR library? If so, where would our service layer lie, and would the service layer be able to reference the DAO classes since the EJB maintains it's own classpath (from what we have read?) Are we looking down the wrong path, or are we completely wrong in our current understanding of JavaEE?
Any assistance is greatly appreciated. We are still in the framework stage of this project and we want to be sure that we will be able to maintain it in the long run.
I second the Maven recommendation. That can add all sorts of sanity to your project structure.
Maven can even generate Eclipse workspaces via mvn eclipse:eclipse
An important clarification on the EJBs note. As of ava EE 6 is you no longer need to separate EJBs from Servlets and can use them together in the very same jar in the war file.
So understand from that that using EJBs or not no longer has any impact on packaging or classloaders as it once did. These are now separate decisions. EARs and classloader separation should now be viewed as a feature you might want to use should you want classloader separation and the complexity it brings. Most applications simply do not need that and are more than fine with just a war file containing servlets, ejbs, jpa entities, cdi beans, jaxrs services and whatever else you need. You are free to decide how you want to separate them or if you want to bother separating them at all.
EJBs do make great DAOs due to transaction management, something you don't get from plain Tomcat but can be made available in Tomcat via TomEE and works fine in Eclipse. You should consider EJBs for that reason, not for dependency reasons.
Side note, as you're new to Java EE, you might find this helpful:
http://openejb.apache.org/examples-trunk/index.html
In order to have things organized when working with Java EE in teams of 1+ people I could suggest:
Use Maven to manage your build process and library dependencies.
Maven has a small learning curve, but once you grasp it you will be grateful. By using Maven you no longer depends on Eclipse to manage your classpath.
A thing about it that I think is really helpful when working in teams is the install feature. Suppose you are woking on the version 1.0 of an EJB module, say core-ejb-module-1.0, and you've got it to a stable state and want everyone working in the project to refer to it from now on.
You then run a maven command like this on it: mvn clean package install
Maven will clean this module, compile it, run tests, create the jar and then install it to a repository that you define. Could be any computer in your company.
Now you may tell the guys working on other projects to update this dependency version on their .pom file and in the next build they run, before compiling, maven will download this library and then use it. Really neat. No more classpath hell.
(There are other ways to always automatically refer to the latest library as stated in this post, but there are some caveats. Anyway it's just an example.)
Use JPA/EJB instead of DAO Pattern.
Some people say DAO meaning any sort of data access, others really mean that they use the DAO Pattern to access objects. If that is your case, you no longer need to use it when using JPA. (At least for most common scenarios).
In my case, I have a generic EntityService which is capable of doing CRUD operations on any Entity and has a centralized query management. Then every EJB's that should perform database related operations may inject this guy and do its job.
As a suggestion, with Maven, you project could be organized as such:
core project structure
core (The pom root)
core-ejb-module (Includes all generic EJB's, like the EntityService for instance.)
core-jpa-module (Includes all JPA generic definitions, like Interfaces, MappedSuperclasses and such.)
core-jsf-module (Includes all JSF generic definitions, like abstract controllers, generic converters and wrappers for FacesContext, etc..)
Now that you have a core generic module setup, you could create:
an application structure
app (The pom root)
app-ear-module (Includes all other modules in this application. Shared jars goes in the ear /lib folder, so all other modules could reference to them.)
app-ejb-module-a (Includes EJB's for the business layer of your application. It uses the core-ejb-module)
app-ejb-module-b (You may have lots of ejb modules. You may even have a project that contains only ejb modules. Other apps will declare their dependency on them via Maven.)
app-jpa-module (Contains definitions for JPA Entities that represents you database tables. Depends on the core-jpa-module)
app-web-module (Holds the pages, Controllers and Converters for this application.)
I think you got the idea. Things tend to be loosely coupled and you may organize your projects as you like.
This is just a simple example to illustrate. I didn't explained a lot about Maven but if you're interested I think it will help you indeed.
I hope it gives you some ideas and may help you in any way.
[]'s
If you can run all the sub-components using the same set of dependencies, you may find it helpful to migrate to a Maven build.
With Maven, you can define a top-level project that manages all the 3rd party dependency versions in one place, so all modules are built, tested and deployed against the same library versions. You are also likely to find Maven a good fit for the multi-module approach you have adopted, as it ensures that a project is rebuilt correctly if one of its dependencies changes.
You would still be able to use dynamic web projects as before; Eclipse will automatically deploy the DAOs as part of the service project (IIRC you need to characterise the DAOs as utility modules).
If you do go down the EJB root, you are correct that each EAR will get its own class-loader, and can therefore use a varying set of dependencies. However, in your position I would tend to look at improving your dependency management first - it'll probably be cheaper and easier.
I'm trying to evaluate whether it's appropriate for our shop to use the NetBeans Lookup API without the whole NetBeans Platform.
So far, I managed to create a project with this code :
for (SomeInterface si : Lookup.getDefault().lookupAll(SomeInterface.class)) {
si.doSomething();
}
I also created a couple of other projects, each with an AnImplementation class implementing SomeInterface, and the accompanying file META-INF/services/path.to.SomeInterface containing a line referencing the class (eg. "other.path.to.AnImplementation").
When I add these implementing projects to the libraries (dependencies) of the main project in the NetBeans IDE, it works fine and I can see the successive results of doSomething() from both implementations.
My question is how to make that work without referencing the sub-projects in the main project ; the jars of the sub-projects wouldn't be included in the generated jar of the main project when building, and one would be able to add or remove them at will, altering the result of the above code.
If I'm not mistaken, this is the behavior advertised in the Lookup API documentation.
Thanks in advance.
Edit: For now, my conclusion is that without the NetBeans Platform (or OSGi ?) it's not possible to detect which service providers are present at startup time. You need to reference their jars in your classpath, and thus to identify them before startup. Feel free to prove me wrong.
You have to reference the sub-project in your calling application, as this puts it on the classpath - If the jar/library is not on the classpath then APIs like the Lookup and ServiceLoader wont be able to find it.
If you use OSGI or the NetBeans platform these systems allow you to change the classpath at runtime.
Geertjans blog has an entry about exactly this(using the Lookup API outside of the NetBeans platform), in his blog he also references John O'Connors blog which contrasts the ServiceLoader and Lookup APIs
EDIT
I've just seen Jon Skeets' answer to a similar question.
You can use the -Djava.ext.dirs=lib property to set a folder (In this case 'libs') as the place where it must lookup jars for your classpath.
In my understanding you don't have to bundle all the modules together with the main project for this to work. All you need is to make sure that your modules are on the classpath when starting the application, because the global Lookup uses the ServiceLoader mechanism under the hood. Based on your question I recommend considering if
using the ServiceLoader directly is a better match for you problem or
some DI framework like Guice is worth a try or
if OSGI offers something useful for you as well and use that.
Don't get me wrong, I absolutely love NetBeans and the NetBeans platform, but in my opinion using the Lookup alone is of limited use because of the possibilities listed above.
Are there any tools that can look at a database, and generate the basic mapping files?
It would be great if it could take a database, and create the actual model (java classes) with annotations, but not sure if that exists?
Hibernate 3 has a toolset called Hibernate Tools that provides an Eclipse plugin and an Ant task that both support Reverse Engineering:
Reverse Engineering: The most powerful feature of Hibernate Tools is a database reverse engineering tool that can generate domain model classes and Hibernate mapping files, annotated EJB3 entity beans, HTML documentation or even an entire JBoss Seam application in seconds!
...
Ant task: The Hibernate3 tools include a unified Ant task that allows you to run schema generation, mapping generation, or Java code generation as part of your build.
For the Eclipse plugin, have a look at this section of the documentation. For the Ant task, have a look at the section about reverse engineering and optionally how to control it.
Note that other IDEs also provide support for reverse engineering (see Hibernate Reverse Engineering for Netbeans 6.5 and Generating Persistence Mappings from Database Schema for IntelliJ).
I just happened to stumble across this problem and I think I have found a perfect tool for the job.
http://hibernatepojoge.sourceforge.net/
Features : (in case you are lazy to go through the provided link)
Java objects representing each table using annotations for use with Hibernate.
A JUnit test case per table that uses the objects generated to create, populate, save, retrieve and compare results
DAO per class
The appropriate enumeration files
Spring and hibernate configuration
DAO layers
A data factory class per schema to return a pre-populated object with random data (for boundary checking, database population, etc)
Also supports:
Join tables including those with additional fields in link tables
Polymorphism/inheritance support
Composite Keys
One-To-One, many-to-one, many-to-many, etc
Multiple schema support (4 modes)
Natural Keys
Enumerations (including those entries which cannot be mapped cleanly onto the java world)
A whole bunch of more stuff (see sample.xml)
I would also like to say that setting this up is quite straight forward; You just have to have a hibernate configuration file and the jar file downloaded from the site. Then it's just a matter executing a jar file, passing the config.xml as a parameter!
If you are using eclipse or ant...
Jboss tools
You might find what you need here, I found it on the fly: MyGeneration.
I know there are others that exist, but I don'T remember by heart. Hope this helps!