Re: Persistence API - magic?
On 11-09-06 07:52 PM, nroberts wrote:
I'm a little confused about how and why the persistence API is even
being used, let alone how it works, in this tutorial I just went
through.
I followed the instructions in this tutorial:
http://programming.manessinger.com/tutorials/an-eclipse-glassfish-java-ee-6-tutorial/
I won't discourage you from trying out Java EE 6, but it's a big jump up
from what you're able to do with JBoss 4. I expect you knew that.
Looking at this particular tutorial, my recommendation is, stick with
the Java EE tutorial, and then more focused third-party tutorials. This
Manessinger fellow is simply covering way too much stuff, with not
nearly enough detail for most of it. I wouldn't steer anyone to this
tutorial - my 2 cents worth. YMMV.
What I'm trying to figure out is how the "entity" classes that eclipse
created with the JPA tools work so I can make my own if I need to.
One tutorial on persistence that I found (
http://www.javaworld.com/javaworld/jw-01-2008/jw-01-jpa1.html?page=3 )
explains how to make them by hand but it uses an orm.xml or
annotations to tell Java what table and what columns to connect an
entity object with.
I won't swear to it but that's probably a good JPA tutorial for JBoss 4,
because it's a JPA 1.0 tutorial and I'd be surprised if JBoss 4 supports
JPA 2.0.
You won't need an orm.xml at this point, if ever - stick to
persistence.xml and annotations.
The eclipse stuff doesn't seem to do that at
all. The orm.xml file exists, but it's practically empty containing
nothing but the root element and xml tag.
Basically, as I suggested above, you can ignore the orm.xml. I've almost
never had one myself.
Here's an example entity:
@Entity
public class Zip extends com.manessinger.util.jpa.Entity implements
Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String code;
private String name;
//bi-directional many-to-one association to Country
@ManyToOne
private Country country;
// ... getters and setters...
}
I was thinking that perhaps it was order based, but the order of the
columns in the zip table to do not match. COUNTRY_ID comes between ID
and CODE. The names are close but the case is different and the
"country" column is actually COUNTRY_ID.
Order is not important. Also (and this anticipates a comment below) JPA
uses a fair bit of convention over configuration, so there are set rules
that dictate why the default PK for the referenced table is COUNTRY_ID.
This is in the JPA APIs and specification.
If you want to change from the defaults then there are various
annotations and annotation attributes that let you do that.
The manessinger Entity base doesn't have anything interesting but some
id utility functions:
public abstract class Entity {
public static boolean isId(Integer id)
{
return (id != null && id > 0);
}
public boolean hasId()
{
return isId(getId());
}
public abstract Integer getId();
}
This is a fairly unnecessary base class for entity classes if that's all
it does. I don't even like the premise of that abstract class. Ignore
it, and keep the "id" (whatever the @Id field is called actually)
accessors in the entity classes.
There's nothing wrong with having a entity base class though.
@MappedSuperclass is designed for this purpose better than what Mr
Manessinger devised. At this stage of the game I wouldn't bother with this.
The information doesn't seem to be at the query site either:
Query q = em.createQuery("select co from Country co");
result = (List<Country>)q.getResultList();
What are the rules that Java is using in order to tell what I want
here and do it? As it stands it seems to almost be intuitively
interpreting what I want to do, which I know is impossible. Why does
this code work?
See above - JPA API docs and the specification. And I strongly recommend
the JPA section of the Java EE tutorial.
AHS