First things first:
I'm aware of this question, which, at the high level of abstraction, asks same what I ask here; however, I find it (and its answer) lacking, therefore, I would like to elaborate on this topic here;
I would kindly ask anyone, who has a good understanding of the formal definitions in the JPA and Hibernate, to help me clarify this mess.
Disclaimer: I am not looking for the basic explanations of what the Entity is and how to use it. I am using Hibernate/JPA for quite some time now.
My question is more about formal definitions, in order to clarify the distinctions of the formal semantics (definitions) between Entity and Persistent Class, to make it crystal-clear how one differs from another and how they are defined.
Initially, I expected the answer to be found in JSR 338: JPA Specification 2.2 and Hibernate 5.0.0 Reference Documentation, but I got quite confused, as I was left with a feeling, that, in this context, both documents are lacking, leaving a big room for these concepts/definitions to overlap and introduce some speculations.
Let's start with JSR 338: JPA 2.2 Specification:
For some (very strange to me) reason, in this entire specification, keyword phrases "Persistent Object" and "Persistent Class" are not found, to wit, they are found only once and twice respectively:
Persistent Object - found in the Javadoc comment, saying nothing interesting (page 221)
Persistent Class - found in the xsd documentation, again, saying nothing much (pages: 378, 529)
and, unfortunately, that is it in this specification, nothing more at all.
The Entity Class, on the other hand, is defined as follows:
An entity is a lightweight persistent domain object. The primary programming artifact is the entity class. An entity class may make use of auxiliary classes
that serve as helper classes or that are used to represent the state of the entity.
which, again, I find extremely lacking for the formal specification document, but at least, this says that it is a persistent domain object.
In the same document, Entity is also defined as a Class (2.1 The Entity Class, page 23).
Even though this might not seem important, it's quite confusing whether it's defined as a Persistent Object or as a Class.
My conclusion based on this specification document:
Persistent Class/Object is not defined in the JPA 2.2 Specification at all;
Entity is defined as persistent object, and(!), as a Class, which is really unclear to me;
In my conceptual understanding, Persistent Object, sounds very much as an object, which is persistable if(!) it will be mapped correspondingly; hence, Persistent Class - as a Class, instances of which are possible to get persisted (i.e. they can be stored into database layer, by conforming to POJO concept), if the class is mapped accordingly. I.e. Persistent Class is a persistable class, and it transforms to Entity, if it has its corresponding mapping definition (either with .hbm.xml or JPA annotations).
Hibernate 5 Reference Documentation
On the other hand, Hibernate defines Persistent Classes, and it does this as follows:
Persistent classes are classes in an application that implement the entities of the business problem (e.g. Customer and Order in an E-commerce application). The term "persistent" here means that the classes are able to be persisted, not that they are in the persistent state.
Am I getting this correct, that Persistent Classes implement the entity means, that my upper understanding is correct, and Persistent Class is just a Java class, which implements the Entity model (without mapping), and in conjunction with its mapping (.hbm.xml or JPA) it becomes an Entity? is Persistent Class + Mapping Definition = Entity correct?
I would also plug here in some snippets from the Java Persistence with Hibernate, Second Edition book:
You wrote a persistent class and its mapping with annotations. - (Summary 2.4);
kind of, differentiates persistent class from its mapping, and that, again, sort of supports the idea, that persistent class and its mapping are distinct concepts, which logically brings the point, that persistent class alone, is not an Entity.
The persistent classes are unaware of—and have no dependency on—the persistence mechanism. - (Chapter 3.2);
clearly states, that Persistent Classes are unaware of the persistence mechanism.
You can reuse persistent classes outside the context of persistence, in unit tests or in the presentation layer, for example. You can create instances in any runtime environment with the regular Java new operator, preserving testability and reusability. - (Chapter 3.2).
also supports the idea, that Persistent Class is not necessarily a mapped Entity.
My conclusion:(based on my initial understanding, which seems to be supported by "Hibernate Reference Documentation" and "Java Persistence with Hibernate, Second Edition" book.)
Persistent Classes are Java classes, which (if needed!) would be conforming with the JPA Specification (according to which, they need to be POJOs and they can be mapped), but they are not Entities if they are not mapped, and they can be used in the outside-of-JPA context, to just operate on them as on ordinary Java objects, or even to present them at the Presentation Layer.
Finally:
As you can see, my question is a bit of a mixture of different resources, showing my evident confusion, as I cannot clearly define the formal, so called scientifically adopted definitions for these two concepts.
Can we clearly define what is the Persistent Class, what is Entity, and what is the the semantic and definitive difference/overlapping between them in terms of JPA and Hibernate?
Under a specific requirement such as not using an abstract base class (or super class), I need to implement a simple hierarchy of two entities one of which is supposed to extend the other but have a different #Id of its own.
My googling about this seems to conclude this is impossible or only on condition that I use a mapped super class (which is forbidden in my case due to a certain policy).
I don't want to duplicate the code of the entity with several dozen attributes and then mutate the duplicate by adding / overriding attributes in order to avoid future maintenance problems, but then I'm stuck in JPA restrictions.
Any help / suggestion will be appreciated.
Having different id types for non-abstract derived entities is not compatible with the JPA inheritance strategies.
What I mean is:
Imagine you have succeeded and different classes in the hierarchy use different incompatible types for the id.
how would you define the DB constraints for a single table inheritance in such a case?
and for joined inheritance?
EDIT: JPA does not distinguish between inheritance strategies when it comes to id definition. And you cannot even be sure that you can use TABLE_PER_CLASS with pure JPA. Virtually all providers implement it, but it is specified as optional and thus the least portable inheritance strategy.
The question remains however. How can the DB constraints look in order to make the table usable unambiguously by the persistence provider? E.g. Which columns should comprise the primary key on DB level?
If you cannot make the parent entity neither abstract nor embeddable nor use the same id, you will have to work around that. How you do that is highly dependant on what you want to achieve and what organizational constraints you have.
There are several possibilities - the least invasive would be composition, having A as a field in B, effectively creating a 1-1 relation.
More ugly approaches could be native and constructor queries but I doubt you want to descend that far.
tl;dr No, it is not possible.
If an aggregate root is meant to hold references to entites that are part of the aggregate, and you are not allowed to reference these entities from other aggregate roots, then how does an aggregate root (aggregation) differ from composition which for me does exactly the same?
The word "Aggregate" in DDD is not derived from the general OO concept of Aggregation.
DDD Aggregate roots are indeed closer to composites if there's a parallel to be made, but they're also much more than that.
I have two classes Parent and Child.
class Child extends Parent {
private String extraField1;
private String extraField2;
...
}
Child class has 2 extra fields extraField1 and extraField2.
Q1. Should I make two diff. tables in the databse: one for Child and other for Parent?
or
Q1. Should I add two columns in the Parent table (each column for one extra field) and store the Child in the Parent table.
=============================== EDITED =======================================
Yes, Child and Parent are classes in the same hierarchy.
Should there be 2 datatables for a Parent and Child class in Java?
There is no universal answer to this question. There are actually several techniques to map an inheritance hierarchy into a relational database and they all have advantages and disadvantages. Choosing one or the other depends on your context.
Scott Ambler details the various approaches in the section 2. Mapping Inheritance Structures of his famous paper Mapping Objects to Relational Databases: O/R Mapping In Detail that I'm quoting below:
(...) In this
section you’ll see that there are
three primary solutions for mapping
inheritance into a relational
database, and a fourth supplementary
technique that goes beyond inheritance
mapping. These techniques are:
Map the entire class hierarchy to a single table
Map each concrete class to its own table
Map each class to its own table
Map the classes into a generic table structure
For a full comparison (with advantages, disadvantages and a recommendation on when to use), have a look at the section 2.6 Comparing The Strategies.
I can't do a better job than him so there is no point at paraphrasing him, just refer to the original paper.
Patterns of Enterprice Application Architecture covers this as well in its chapters on Single-table inheritance, Class-table inheritance, and Concrete-table inheritance.
The coverage is similar to what Pascal has said. There's no One True Way, but the book does give you a good breakdown of costs and benefits, e.g.
The strengths of Concrete Table Inheritance are:
Each table is self-contained and has no irrelevant fields. As a result
it makes good sense when used by other
applications that aren't using the
objects.
There are no joins to do when reading the data from the concrete
mappers.
Each table is accessed only when that class is accessed, which can
spread the access load.
The weaknesses of Concrete Table Inheritance are:
Primary keys can be difficult to handle.
You can't enforce database relationships to abstract classes.
If the fields on the domain classes are pushed up or down the hierarchy,
you have to alter the table
definitions. You don't have to do as
much alteration as with Class Table
Inheritance (285), but you can't
ignore this as you can with Single
Table Inheritance (278).
If a superclass field changes, you need to change each table that has
this field because the superclass
fields are duplicated across the
tables.
A find on the superclass forces you to check all the tables, which leads
to multiple database accesses (or a
weird join).
What's the difference between Association and Dependency? Aren't they both the same thing? as if class A is associated with B then Class A is dependent on B ie. there's a dependency between A and B.
When you are speaking in UML terms, an association allows one object to send a message to another object by instantiating it.A dependency, on the other hand, means that one objects relies on another object and it might change if the other object changes, however there are no instances of those to objects.
http://en.wikipedia.org/wiki/Dependency_(UML)
Similar topic in SO: Does an association imply a dependency in UML?
In the above post, there's a reference to the UML's Superstructure document:
OMG Unified Modeling LanguageTM (OMG UML) Superstructure (PDF format)
Very technical but can be a good read as well.
Dependency relationship does not require direct communication between two elements. It just means that one object relies on a fact that another object exists.