Discussions

In the TSS discussion forums, one user posted an interesting question about JPA and custom types. The JPA specification, in section 2.1.1, says that only certain types of fields can be persisted, but it's hard to deny that custom types can occasionally be useful, especially when considering some other aspects of the JPA specification.
The persisted types, from the specification's section 2.1.1, are:

This would eliminate non-serializable types (which isn't a horrible thing, strictly speaking) and a few others, but what about types that self-validate? Consider a java.net.URL instance; since URL is Serializable, it's supposed to be supported by JPA. However, the Toplink Essentials implementation fails on store (noted already as a bug, "@Column java.net.URL getUrl() { } fails on store"), which is clearly outside of the specification's requirements.
There are two problems here.
One is that Toplink Essentials clearly has a failure in implementation of the specification, which is easy enough to fix. The tests clearly are not checking some of the possible problem cases; a fix would simply add the failing cases, and add code to check for serializable fields.
The other, however, is the simplistic rendering of custom types as "serializable" content. If the URL was rendered as a byte stream - a LOB - then it would function properly, but a LOB is normally incredibly expensive for such a tiny amount of data. Hibernate has the ability to map custom types into a table; why does JPA not support something similar?

There should be at least a custom mapping feature if everything else fails. I dont know the JPA spec on this point but it should be a product decission to support custom mapping features. Normally you create a class which implements some interface and this class is responsible for doing persistence and loading of custom types as you define it. For instane i am persisting java.util.Locale with this approach. Kodo does this quite well, even when the API has changed from kodo3 to kodo4 ;-)
Marc Logemann
http://www.logemann.org

There should be at least a custom mapping feature if everything else fails.

JPOX does it "out of the box" ... for URL, Locale, and many more. Why is there a need for custom mapping for such simple types ? Fair enough for user types but these are standard JDK types that have been around for some time. Why are specs so weak in this respect?

The other, however, is the simplistic rendering of custom types as "serializable" content. If the URL was rendered as a byte stream - a LOB - then it would function properly, but a LOB is normally incredibly expensive for such a tiny amount of data.

And that's the center of this "bug".
This bug, at the moment, is programmer error. Somehow the coder is assuming that the JPA just "knows" that a URL can be persisted as a string, and no doubt has a character column in the database.
But to the JPA, URL is no different from ArbitrarySerializableObject -- whether thats a wrapper for 1 byte several GB worth of data. It simple doesn't have any idea.
Why the JPA doesn't have any kind of conversion framework is a guess, as I didn't follow the development. Perhaps the vendors couldn't come to a reasonable agreement that would have been readily implementable in the assorted core technologies that the JPA current wrapping (Hibernate, Toplink, Kodo, etc.). Maybe they were waiting for some better Real World experience with vendors trying to lever something on to the JPA (no doubt you can tweak the JPA on top of Hibernate to do these conversions, but that code may not be portable).

The reason JPA does not standardize custom types is that it isn't easy to come up with a simple API that will work with all JPA implementations. Different vendors use quite different strategies for stuff like dirty checking (for example, Hibernate wants you to define "equals" when you write a UserType, some other implementations don't). If you look at Hibernate's UserType and CompositeUserType interfaces, you'll see that they are pretty complex already. Now add in stuff that Hibernate doesn't need but other implementations do need, and it will get even more complex. Now, probably you could dumb it down a bit for the spec, by restricting the capabilities of custom types, but it would still be quite complex.
And it would have taken us much too long to reach agreement on something like that given the extremely limited time window we had to produce the EJB3 spec. So we decided since vendors can, for now, all provide this functionality as spec extensions, and since it is relatively "advanced" functionality, that we would revisit this in the next rev of the spec.

I still find it disappointing that after easily 10 years of practice with O/R mapping and multiple capable products in that field, we are not able to come up with a standard that includes all well-established practices, whatever the reason may be. Makes me wonder about the value of the JCP.
I have always looked at UserTypes as one of the fundamental mapping options at the table level, along with embedded objects. I have also already expressed my frustration about the lack of support for identifying relationships (foreign keys that are also part of the primary key) over at http://www.javalobby.org/java/forums/t77656.html. It almost looks like by the time we have a complete standard, relational databases will have gone away (just joking, I dont see them going away anytime soon)
For now, my conclusion is "code against JPA, but be prepared to move into proprietary extensions at any point".
Christian

I still find it disappointing that after easily 10 years of practice with O/R mapping and multiple capable products in that field, we are not able to come up with a standard that includes all well-established practices, whatever the reason may be. Makes me wonder about the value of the JCP.

You expect a group of disparate interests to Home Run a specification that they all need to live with, and you expect them to do it in a elegant fashion.
Groups like the JCP, and any other "rule making" committee, are all about advancing the agenda, doing it in a practical way, and doing it in a way that most of the parties can agree too.
The phrase "designed by committee" rest squarely on the shoulders of the compromises that poke through the finished product. Why did They do it this way? Why didn't they do X? How come they didn't push it just the next level? It's so OBVIOUS, using backward facing binoculars from my armchair, they should be taking Path Q instead of Path Z.
If you want succinctness of vision and purity of purpose, look not at any committee or group. Look to the mad genius in his laboratory.
But, while a mad genius can advance a field (Gavin and ORM), groups like the JCP advance the entire industry (JEE and JPA). And despite the flaws inherent in any committee, done well and by advancing the industry, they can raise the tide for everyone.
Last year, you may have had to fight to get some ORM solution beyond CMP in to your shop. Next year, the shop is going to force it down your throat as they upgrade, and the shop is going to have a wide variety of imperfect, yet mostly equivalent, solutions to the problem as the different vendors promote and tune their solutions.
So, rather than damning the organization, perhaps a look around the entire industry of Java will show you the actual value a group like the JCP, however imperfectly, provides.
The JCP is the "Microsoft" of Java community. If you wish to work in Enterprise Java, you WILL be in the JCP and the standards they publish shadow. Better that monolith be somewhat community based than what we have with Microsoft, don't you think?

The JCP is the "Microsoft" of Java community. If you wish to work in Enterprise Java, you WILL be in the JCP and the standards they publish shadow. Better that monolith be somewhat community based than what we have with Microsoft, don't you think?

I think we have good reason to keep pushing in that direction, then. Some of us remember well that it was also a committe that sent us into the dark ages of EJB1/2 persistence (as Rod J. puts it), which may have been an advancement in the business sense, but it was a setback technologically.
Let me emphasize, however, that I am not comparing EJB3 JPA with EJB1 or 2. JPA is based on solid experience in the field, no doubt.
-C

yes, after reading up on it, I can confirm that that is the concept I was referring to. It seems it is specified in JDO2 (which you refer to), but not in JPA. Too bad,because JPA is the thing of the day.
The term "Compound Identity" sounds somehwat confusing, because it is used in the JPA context as denoting a primary key that is made up of multiple columns, which JPA does of course support. What JPA doesnt specify (and some products dont even have an elegant workaround for) is the case where an entity relationship becomes (part of) the key.
Christian

The term "Compound Identity" sounds somehwat confusing, because it is used in the JPA context as denoting a primary key that is made up of multiple columns, which JPA does of course support. What JPA doesnt specify (and some products dont even have an elegant workaround for) is the case where an entity relationship becomes (part of) the key.

Christian

Isn't that covered by the "Compound Identity"?What prevent you to include the column containing the foreign key to the linked entity in the primary key?
ZartC.

zart,
Just to be clear: "Compound Identity" is the term from the JDO spec, JPA speaks of "composite keys" only.
The JPA spec doesnt even mention the possibility of using a relationship as a key. However, the "Pro EJB3" book by Mike Keith (which I heartily recommend BTW) does.
In order to map an identifying relationship using most JPA products you have to maintain additional fields in the entity which, as you suggest, mirror the primary key of the linked entity. You will then have duplicate mappings for the foreign key columns - once for the relationship, and once for the additional fields. All described in suffiecient detail in Mikes book. However, as Mike points out, this is an unspecified procedure that may not work with all products.
Christian

The reason JPA does not standardize custom types is that it isn't easy to come up with a simple API that will work with all JPA implementations. Different vendors use quite different strategies for stuff like dirty checking (for example, Hibernate wants you to define "equals" when you write a UserType, some other implementations don't). If you look at Hibernate's UserType and CompositeUserType interfaces, you'll see that they are pretty complex already. Now add in stuff that Hibernate doesn't need but other implementations do need, and it will get even more complex. Now, probably you could dumb it down a bit for the spec, by restricting the capabilities of custom types, but it would still be quite complex.

And it would have taken us much too long to reach agreement on something like that given the extremely limited time window we had to produce the EJB3 spec. So we decided since vendors can, for now, all provide this functionality as spec extensions, and since it is relatively "advanced" functionality, that we would revisit this in the next rev of the spec.

My 2 cents,
There is really nothing wrong with having vendor-specific features. Sometimes its a *good* thing when a spec doesn't define a specific feature, as in this particular example. Sometimes I think people really confuse specifications and products. A specification is not a product.
Bill

Bill, the purpose of a specification is to standardize a technology or API in such a way that I can happily program against it and switch implementations anytime. This is not a new concept I guess. If a spec doesnt cover a core aspect of the technology it adresses, then it fails in that aspect.
The only thing I would leave open to discussion is whether UserType/conversion functionality is at the core of ORM technology. I would say it certainly is quite close.
-Christian

Bill, the purpose of a specification is to standardize a technology or API in such a way that I can happily program against it and switch implementations anytime.

+1

The problem here Steve is premature standardisation versus experimentation, innovation and natural selection. I've seen this mistake made again and again. The standards that succeed are the ones that are conservative in scope, only standardising features that are well understood and generally accepted as successful. More esoteric and experimental features should be left to the market place. Over time through natural selection a given solution will rise to the fore. Only then should it be standardised.
What is worst than no standard is a poor standard. Many Java standards have suffered from premature standardisation IMO. So when we don't know whether an approach is a good idea the standard should be silent and vendors and others should be able to offer solutions of their own.
We as developers then have a choice. We either implement non-standardised functionality ourselves or rely on a vendor/project specific extension. Good examples of this approach are the raft of Web Frameworks that build on the Servlet API and the various ORM solutions that sit above JDBC.
Is JPA a premature standard? Possibly. I haven't looked at it so I don't know and only time will tell. But my advice to anyone involved would be to stick to the lowest common denominator amongst the already successful ORM solutions and don't try and specify anything that is still unproven.
Paul.

But my advice to anyone involved would be to stick to the lowest common denominator amongst the already successful ORM solutions and don't try and specify anything that is still unproven.

Paul, I dont know how much experience with ORMs you have, but none of the issues we discuss here are unproven, as has been mentioned several times. The problems are well understood since over a decade, and all products I know already adress them in similar ways. Certainly none of this was/is esoteric or experimental.
The only missing piece was the definition of a common API, and possibly the unification of the slight differences in semantics. It is unfortunate that there was no time to finish this up, but we'll hope for the next release.
Christian

But my advice to anyone involved would be to stick to the lowest common denominator amongst the already successful ORM solutions and don't try and specify anything that is still unproven.

Paul, I dont know how much experience with ORMs you have, but none of the issues we discuss here are unproven, as has been mentioned several times. The problems are well understood since over a decade, and all products I know already adress them in similar ways. Certainly none of this was/is esoteric or experimental.

The only missing piece was the definition of a common API, and possibly the unification of the slight differences in semantics. It is unfortunate that there was no time to finish this up, but we'll hope for the next release.

I don't think so - it is coming at the right time. There is nothing in the JPA spec that is "wrong"; a few things may be underspecified (and I am sure they will be addressed in the next rev), but no aspect of the spec is flawed. We already see a lot of people migrating to JPA precisely because of the advantages that standardization brings: great support in tools, good support from your appserver vendor, lower cost of switching to another implementation etc.

great support in tools, good support from your appserver vendor, lower cost of switching to another implementation etc.

Petr, which tool do you have in mind? I am currently looking into the free offerings (Eclipse Dali mostly), and cannot say I am impressed (to be fair, Dali is at 0.5).

Christian

I wanted to avoid another product plug, but it looks like I can't ;-) Try NetBeans 5.5, which has full support for Java EE 5, including JPA. Beta 2 is out right now, daily builds are even more stable, and the final version will be released during the fall. We will appreciate if you post any comments about your experience to nbj2ee at netbeans dot org and/or file bug reports, or write to me at petr.jiricka at sun.com. Thanks.
Petr

Perhaps I've been spoiled by Hibernate over the past few years, but it is disappointing to see so many useful things left out of the JPA spec. I can see some of the complexity in things like the Criteria API and Custom Types - but I disagree that they are 'exotic' or 'advanced'. The Criteria API that is in Hibernate is probably advanced functionality and not completely necessary - but Custom Types? Those are quite necessary in many cases to acheive proper O/R mapping.
Granted, we can (and do) use Hibernate's functionality for this and it works fine, but it kind of diminishes the value of using JPA if a good portion of our code still depends on a specific implementation.
I can certainly see the time constraints causing these (and other) pieces of functionality left out of the EJB3 spec, but do you see them being seriously considered at all in future revisions of the JPA spec?

Even if custom types are supported as implementation extensions, it sure isn't easy to find out about. I spent an hour yesterday with google trying to find out if we should use Hibernate and a usertype to map Oracle Spatial sdo_geometry types to JGeometry java type, or if this was possible to do using JPA.
Reading the comments here, I guess it is possible to use JPA with hibernate as implementation, and use the same usertypes as I would do if I was using "pure" hibernate?
But then I might want to use functions like sdo_geom.relate in my queries... is that possible in JPA?
Recommended reading for practical implementations of JPA? All I find is the spec, or simple tutorials. Nothing in between describing the actual implementation... or would that be the hibernate docs? Everyting I can do in hibernate, I can do in hibernate/jpa?

I spent an hour yesterday with google trying to find out if we should use Hibernate and a usertype to map Oracle Spatial sdo_geometry types to JGeometry java type, or if this was possible to do using JPA. But then I might want to use functions like sdo_geom.relate in my queries... is that possible in JPA?

JPA provides no provision for specifics like spatial types. Such support is vendor-specific with what they have defined in JPA.
In case it's of use to you, JPOX provides a significant proportion of what you mention out of the box with no need for custom mappings ( http://www.jpox.org/docs/1_1/spatial.html ). Currently provides Oracle JGeometry, but is being extended currently to incorporate standards based support for OGC SFA with Oracle, MySQL, Postgresql, and DB2 in current scope.

JPA provides no provision for specifics like spatial types. Such support is vendor-specific with what they have defined in JPA.In case it's of use to you, JPOX provides a significant proportion of what you mention out of the box with no need for custom mappings

Before this "news" thread degenerates into a product pitch free-for-all (oops, too late ), I just want to say that no spec (neither JPA nor JDO that JPOX is the RI for) specifies mappings for URLs, custom types, or using stuff like Oracle spatial. (I thought that JDO specifically prohibited non-specified system-defined classes from being persistent fields, but I may have misinterpreted something I read in the spec).
If the floor is open to talking about vendor features then, being an Oracle product, TopLink obviously offers more built-in support for Oracle-specific features (including spatial, historical querying, VPD, Oracle hints, etc. etc) than other products, but that is not really the point, just another product pitch... ;-)
-Mike

I thought that JDO specifically prohibited non-specified system-defined classes from being persistent fields, but I may have misinterpreted something I read in the spec

Nothing of the sort. JDO(2) explicitly says that implementations can optionally implement several specific types, and doesn't prohibit supporting others either (it simply defines whether particular types are persistent by default and whether they are mandatory for an implementation).
Back to plugging your book ;-)

I thought that JDO specifically prohibited non-specified system-defined classes from being persistent fields, but I may have misinterpreted something I read in the spec

Nothing of the sort. JDO(2) explicitly says that implementations can optionally implement several specific types, and doesn't prohibit supporting others either (it simply defines whether particular types are persistent by default and whether they are mandatory for an implementation).

I looked for the section that I had stuck in my mind and found:
"Except for system-defined classes specially addressed by the JDO specification, system-defined classes (those defined in java.lang, java.io, java.util, java.net, etc.) are not persistence-capable, nor is a system-defined class allowed to be the type of a persistent field."
There might very well be another section that you know about that overrides this one but it doesn't really matter to me either way. My point was only that we have not been able to give complete coverage of these sorts of issues in the specs yet. Give us a chance, though. With people like Gili, Christian and others that are continuously posting their comments and use cases to us we will hopefully be able to keep the priorities real and representative.
-Mike

TopLink obviously offers more built-in support for Oracle-specific features (including spatial, historical querying, VPD, Oracle hints, etc. etc) than other products, but that is not really the point, just another product pitch... ;-)

-Mike

Hm, historical querying looks really nice... :)
The only thing I can find about spatial though, is a post in the oracle technet forums...?
/Magnus

Even if custom types are supported as implementation extensions, it sure isn't easy to find out about.

Your implementation doc will typically guide you towards what is and isn't part of the spec.
Recommended reading for practical implementations of JPA? All I find is the spec, or simple tutorials.That is why we write books on the topic. I recommend the recently released book that Christian referred to in the other thread: Pro EJB 3: Java Persistence API... :-)
-Mike

and I would like to add that it is a good thing to discuss anything related to EJB3, whether it be the spec as such of vendor extensions. It even justifies pulling up some obscure thread from the dicussion fora.
I think this is much more valuable than reading about the umpteenth web framework being published

In the TSS discussion forums, one user posted an interesting question about JPA and custom types ...

Joe, it must be a very slow news day indeed if you are reduced to cruising through TSS forums for news. First you take another comment completely out of context and spread FUD about Kodo and now you are doing the same with TopLink. Look out, Gavin, Hibernate must be next on the JPA hit list. Is this the cost of JPA success? Ouch. Joe, give us some news, don't try to generate some.
FTR, the bug number listed above is related to a somewhat unspecified case in the current spec in that the user is relying upon schema generation. This is not a feature that the spec requires or describes, thus it is not specified what should be generated for a serializable object. The results are NOT a failure in how TopLink implements the spec.
The next point is that TopLink, like Kodo and Hibernate, has proprietary support for persisting any type and allowing applications to dictate some user behavior for the transformation of the class to and from the database. This is stock stuff that has been around for years, and it actually did start out on our list of mappings to support. As mentioned already, though, we simply could not justify spending the extensive time that would have been required to try to reach consensus on it when more important features needed to be completed and included. It is, of course, on the list to discuss for the next release, but for now people need to revert to their vendors functionality for custom mappings.
Hey, in other news, I was going through the forums and found that it is not possible to download tech talks as a file. See http://www.theserverside.com/discussions/thread.tss?thread_id=40980. Does this mean a headline is coming?
TSS site fails to serve needs of its readers
;-)

Just curious, was it my post? :) http://www.theserverside.com/discussions/thread.tss?thread_id=41833
You know, I've been asking this question on and off for months now and I haven't gotten a single reply in any discussion forum I had posted in. I think that's part of the problem. If someone would have told me in black and white this wasn't supported I would have fired off an email to the EJB3 specification team and pushed them to include it. I naively assumed it was just me and let it go. Oh well :)
Nostalgia aside, I plan on dealing with it by defining getPropertyAsSerializable() for EJB3 and making the user-method getProperty() @Transient. Ugly, but I think it will work ;)

I don't know if it is possible to do with JPA or not. I am using google appengine and I want to achiever some thing like below.
I have an entity user profile which has fields like
- Gender
- ProfileCreatedBy
- Height etc
It can have some predefined values like Male/Female or Self
I don't want to model them as strings (Although I can do it)
But I don't find any way to treat them as user defined types.
I know hibernate has way to do it.
jsptube

TechTarget provides technology professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective purchase decisions and managing their organizations technology projects - with its network of technology-specific websites, events and online magazines.