JPA Hibernate Typedef - java

In the project I am using JPA with Hibernate implementation. All the entities are annotation based and listed in persistence.xml.
All Entities are packaged into jar.
I need to define a typedef for few properties(in all the entities) which are a string to a enum type. In DB the Columns is varchar. How can i achieve this?
Can I achieve this by adding hbm.xml and hibernate-cfg.xml?
Thanks in advance.

Straight from the documentation:
#org.hibernate.annotations.TypeDef and
#org.hibernate.annotations.TypeDefs allows you to declare type
definitions. These annotations can be placed at the class or package
level. Note that these definitions are global for the session factory
(even when defined at the class level). If the type is used on a
single entity, you can place the definition on the entity itself.
Otherwise, it is recommended to place the definition at the package
level.

If you can't change the classes but can change the hibernate config, I think you could change hibernate.mapping.precedence to be "hbm,class", and then add hbm files with all the information in the annotations for the relevant classes. There is hbm syntax to specify a UserType or an EnumType. You'd also have to define your UserType class if using that.
You might want to try this out on a test project before taking my word for it, I'm assuming it would work but I don't know for sure.
Copying all of the persistence information from annotations to hbm could be a pain, and would duplicate information. Try if possible to find a way to add the annotations to the classes themselves.

Related

Is it necessary to use #Embedded for Spring?

I have models with nested entity inside them. Is it necessary to write annotation #Embedded and #Embedeable or it's not necessary in actual Spring version?
Yes you still need to use these in Spring, since these are JPA annotations and are necessary when you are embedding a given type within another entity.

Java find and compare members by string (maybe JPA feature?)

I've got alot of beans with attributes, which are derived from database tables with JPA. The users shall be able to enter any column name and a value as a string, and the app shall automatically find the correct member in the one of the beans.
I must use JPA, otherwise I would use some JDBC meta data to put all columns and values into a normal map. Is something like this possible with JPA? It only has to work from database to beans, I don't want to persist changes.
If this doesn't work, can I somehow analyze member names programmatically at runtime?
The EntityManagerFactory has a getMetamodel() method, which returns its MetaModel. From this MetaModel, you may ask for the MetaModel of every entity class, and discover all its attributes, their types, etc.
In case the JPA part doesn't work, you can access class members (fields, methods) of your class as follows:
Field[] fs = YouClass.class.getDeclaredFields();
Details for accessing different members are on this link

Automatically Persisting a Complex Java Object

For a project I am working on, I need to persist a number of POJOs to a database. The POJOs class definitions are sometimes highly nested, but they should flatten okay, as the nesting is tree-like and contains no cycles (and the base elements are eventually primitives/Strings). It is preferred that the solution used create one table per data type and that the tables will have one field per primitive member in the POJO. Subclassing and similar problems are not issues for this particular project.
Does anybody know of any existing solutions that can:
Automatically generate a CREATE TABLE definition from the class definition
Automatically generate a query to persist an object to the database, given an instance of the object
Automatically generate a query to retrieve an object from the database and return it as a POJO, given a key.
Solutions that can do this with minimum modifications/annotions to the class files and minimum external configuration are preferred.
Example:
Java classes
//Class to be persisted
class TypeA {
String guid;
long timestamp;
TypeB data1;
TypeC data2;
}
class TypeB {
int id;
int someData;
}
class TypeC {
int id;
int otherData;
}
Could map to
CREATE TABLE TypeA (
guid CHAR(255),
timestamp BIGINT,
data1_id INT,
data1_someData INT,
data2_id INt,
data2_otherData INT
);
Or something similar.
I would use the standardized Java Persistence API (JPA), preferably with annotations. Regarding your requirements:
This is not required by the specification but most JPA providers (all major implementations do) support DDL generation from the mapping metadata.
EntityManager#persist(Object entity) does that.
<T> T EntityManager#find(Class<T> entityClass, Object primaryKey) does that.
As hinted, JPA is an API, you need an implementation to use it. My preference goes to Hibernate Entity Manager or EclipseLink (see this previous question).
Hibernate can help you solve all the three problems you listed.
(1) You need to annotate your entity classes so Hibernate is able to map between classes/objects to tables/rows. Hibernate uses a convention over configuration approach so it is possible to use just a few annotations and have a complete o/r mapping ready for use. You could use the hibernate.hbm2ddl.auto configuration option to instruct Hibernate to automatically validate/export and schema DDL when the session factory is first created.
(2) / (3) Hibernate has enough information about classes, database schema and mappings to allow it generate SQL statements for simple CRUD operations with minimal effort. You can fine tune how Hibernate loads and persists a tree of objects. Association mapping annotations have the fetch and cascade options that let you specify how associated objects are fetched (lazy / eager) and how operations are propagated through the object tree. Please refer to the Hibernate documentations for the details about these options.
If you are new to Hibernate, I recommend the good Hibernate documentation as reference and the book Java Persistence with Hibernate for the deeper understanding about the framework (it has very good sections about fetching and cascading).
In a typical scenario, Hibernate requires just a bit of configuration (one hibernate.cfg.xml file). You can define the mappings using XML files (no good) or annotations (the "default" option for new projects).
You tagged your question as Hibernate. Have you tried using Hibernate for this?
As long as you define well how collections should be mapped (e.g., one-to-many), I've found it generally very effective for this kind of thing.
The Hibernate tutorials provide a lot of examples for situations that are similar to the code you provided.
A highly recommended framework is JPersist, an extremely simple Database-to-POJO framework. No XML or annotations needed. I use it it my project because if I want a new table object, I simply create a bean.
The issue though in your situation is your wanting something to setup the database for you. Doing that would be very hard and your asking alot from a framework. With JPersist, you should be able to create a db table from class name and columns from fields, and then use phpMyAdmin's designer to resolve references.
5 min of reading the documentation for JPersist now will save hours in development time later.
JPA provides sufficient options to do this. For example you can use #Embeddable and #Embedded:
#Embeddable
class TypeB {
int id;
int someData;
}
class TypeA {
....
#Embedded
TypeB data1;
}
You can either manually create the underlying schema, or let something like hbm2ddl.auto=update to create it for you.

JAXB: #XmlTransient on third-party or external super class

I need some help regarding the following issue with JAXB 2.1.
Sample: I've created a SpecialPerson class that extends a abstract class Person.
Now I want to transform my object structure into a XML schema using JAXB. Thereby I don't want the Person XML type to appear in my XML schema to keep the schema simple. Instead I want the fields of the Person class to appear in the SpecialPerson XML type.
Normally I would add the annotation #XmlTransient on class level into the Person code.
The problem is that Person is a third-party class and I have no possibility to add #XmlTransient here. How can I tell JAXB that it should ignore the Person class without annotating the class. Is it possible to configure this externally somehow?
Have you had the same problem before? Any ideas what the best solution for this problem would be?
OK, this was a pain in the you-know-what. Finally, after sifting through many a blog postings, here's what I did,
added a package-info.java class in the 'third-party class' package like this,
#javax.xml.bind.annotation.XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.NONE)
package third-party-package;
In my case, it was just one package so it was easy. Obviously, you will have to do this for for every separate package structure. I haven't tried doing it at a master package level.
You can provide mappings for third-party classes using Annox.
The EclipseLink JAXB (MOXy) implementation offers a means of representing the metadata as XML that you could use:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
You can specify some of the metadata using annotations, and the rest as XML. Below is what your document would look like:
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm">
<java-types>
<java-type name="Person" xml-transient="true"/>
</java-types>
</xml-bindings>
You can annotate your SuperPerson class with #XmlTransient, that will instruct JaxB not to automatically marshal all properties. And then annotate each getter (or field) you want to serialize with the relevant annotation.
This approach is not very elegant, but it should work
I posted another solution with complete code here
JAXB External Custom Binding XJC Issue - Parsing results in empty node
in case you are interested.

How can I inherit Hibernate filters with annotations?

I'm trying to set up a Hibernate filter with annotations. I would like to specify it in a base class and make all sub classes use it but whenever I try to enable it, Hibernate fails to find the filter. Is it possible at all to inherit filter annotations?
Since 3.5.0 it's at least possible for #MappedSuperclass.
Not sure if that helps you... see: HHH-4332
Are you using the hibernate filter directly, or are you extending the hibernate filter for your own purposes? Annotations aren't inherited by default in Java, although if you were writing the annotation yourself, and I'm assuming hibernate didn't do this on their annotations, you can specify the #Inherited meta-annotation on your annotation to make it inherit. This only works for Type level annotations, though. Also, some people write an annotation manager to simulate full inheritance. You could do something like that, either extend hibernates mechanism or write a preprocessor that adds the annotations where they should have been inherited.
What John Ellinwood wrote is precisely the case. That is why #Filter needs to be specified on all subclasses, at least in Hibernate Annotations 3.4.0-GA.
Furthermore, although that might not be apparent, you will need the same annotation on all mapped collections of that class, if you expect those collections to be susceptible to filtering as well.

Categories