Here are some points I had notes while reading Keith's book.....
..<Rough Notes>
@OneToMany = @ManyToOne Bid
There are two important points to remember when defining bidirectional one-to-many
(or many-to-one) relationships:
1. The many-to-one side is the owning side, so the join column is defined on that side.
2. The one-to-many mapping is the inverse side, so the mappedBy element must be used.
Failing to specify the mappedBy element in the @OneToMany annotation will cause the provider
to treat it as a unidirectional one-to-many relationship that is defined to use a join table
(described later). This is an easy mistake to make and should be the first thing you look for if
you see a missing table error with a name that has two entity names concatenated together.
@ManyToMany Bid
Note that no matter which side is designated as the owner, the other side should include
the mappedBy element, otherwise the provider will think that both sides are the owner and
that the mappings are separate unidirectional relationships.
a join table, and each many-to-many relationship must have one.
@ManyToMany
@JoinTable(name="EMP_PROJ",
joinColumns=@JoinColumn(name="EMP_ID"),
inverseJoinColumns=@JoinColumn(name="PROJ_ID"))
private Collection<Project> projects;
The names are plural for the case when there may be multiple columns for each foreign key when either the owning
entity or the inverse entity has a multipart primary key.
Of course, the owner is basically picked at random by the developer
Here----------
Employee is the OWNER, (-linked to many projects)
Project = INVERSE has an employees attribute that contains the collection of Employee instances. (linked to many employees)
When no @JoinTable annotation is present on the owning side, then a default join table named <Owner>_<Inverse> is assumed, where <Owner> is the name of the owning entity and <Inverse> is the name of the inverse or non-owning entity.
The default name of the join column that points to the owning entity is the name of the attribute on the inverse entity that points to the owning entity, appended by an underscore and the name of the primary key column of the owning entity table. So in our example the Employee is the owning entity, and the Project has an employees attribute that contains the collection of Employee instances. The Employee entity maps to the EMPLOYEE table and has a primary key column of ID, so the defaulted name of the join column to the owning entity would be EMPLOYEES_ID. The inverse join column would be likewise defaulted to be PROJECTS_ID.
If Unidirection OneToMany
one side of a many-to-many relationship does not have a mapping to the other, then it is a unidirectional relationship. The join table must still be used; the only difference is that only one of the two entity types actually uses the table to load its related entities or updates it to store additional entity associations.
@JoinTable(name="EMP_PHONE",
joinColumns=@JoinColumn(name="EMP_ID"),
inverseJoinColumns=@JoinColumn(name="PHONE_ID"))
private Collection<Phone> phones;
// ...
}
Note that when generating the schema, default naming for the join columns is slightly
different in the unidirectional case because there is no inverse attribute. The name of the join
table would default to EMPLOYEE_PHONE and would have a join column named EMPLOYEE_ID
after the name of the Employee entity and its primary key column. The inverse join column
would be named PHONES_ID, which is the concatenation of the phones attribute in the Employee
entity and the ID primary key column of the PHONE table.
Always use the interface for collection . This is because when the entity instance becomes managed, the persistence
provider may have replaced the initial concrete instance with an alternate Collection implementation class of its own.
@OrderBy("name ASC")
private List<Employee> employees;
Default is ASC � can have DESC
@OrderBy("status DESC, name ASC"). Of course the prerequisite for using an attribute in an @OrderBy annotation is that the attribute type be comparable.
@ManyToOne
@JoinColumn(name="ADDRESS_LOOKUP_ID",
referencedColumnName="ADDRESS_LOOKUP_ID")
private AddressLookup addressLookup;
Cardinality (count) and ordinality(optional r/s or mandatory r/s)
@Entity
public class Department {
// ...
@OneToMany(mappedBy="department")
@MapKey(name="name")
private Map<String, Employee> employees;
// ...
}
When the collection is of type Map but no @MapKey annotation is specified, the entities will
be keyed by their primary key attributes.
Every time an operation is invoked on the entity manager, it checks to see if a persistence context is associated with the transaction. If it finds one, the entity manager will use this persistence context. If it doesn�t find one, then it creates a new persistence context and associates it with the transaction. When the transaction ends, the persistence context goes away.
Because there is a new transaction for each method, the entity manager will use a different persistence context
each time.
public void setName(String name) {
dept.setName(name);
}
//Name not stored in database because the PersistenceContextType is Transaction and here dept is not attached�or managed. Until we do a find for it.
We refer to the Department entity in this case as being detached from a persistence context. The instance is
still around and can be used, but any changes to its state will be ignored
So what if the method had the transaction attribute NotSupported ?
Since PCxt is created for the given Tx/ = if no Tx implies no PCxt creation???
What is the difference between NotSupported and Never? NotSupported does not raise an exception when the Tx is existing for the op. Never raises exception.
Look at PcxtType to determine if the changes are commited or not. Is it managed in this method given the type
Unlike the persistence context of a transaction-scoped entity manager that begins when the transaction begins and lasts until the end of a transaction, the persistence context of an extended entity manager will last for the entire length of the
conversation.
What separates Java SE and Java EE for applicationmanaged entity managers is not how you create the entity manager but how you get the factory.
In terms of the persistence context, the application-managed entity manager is similar to an extended container-managed entity manager. When an application-managed entity manager is created, it creates it own private persistence context that lasts until the entity manager is closed. This means that any entities managed by the entity manager will remain that way, independent of any transactions.
There are several different entity manager types, but all use a persistence context internally. The entity manager type
determines the lifetime of a persistence context, but all persistence contexts behave the same way when they are associated with a transaction.
There are two transaction-management types supported by the Java Persistence API.
1.resource-local transactions
2.Java Transaction API, or JTA transactions.
Container-managed entity managers always use JTA transactions, while applicationmanaged
entity managers may use either type. AMAZING.
PCxt and Tx = Relationship
Transaction synchronization
is the process by which a persistence context is registered with a transaction so that
the persistence context may be notified when a transaction commits. The provider uses this
notification to ensure that a given persistence context is correctly flushed to the database.
Transaction association
is the act of binding a persistence context to a transaction. You can also
think of this as the active persistence context within the scope of that transaction.
Transaction propagation
is the process of sharing a persistence context between multiple container-managed
entity managers in a single transaction.
transaction-scoped persistence context creation is lazy. An entity manager will create
a persistence context only when a method is invoked on the entity manager and when there is
no persistence context available.
must first check if there is a propagated persistence context. � if exists use else create and use the created one for propaged Tx. So lazy PCxt creation.
This behavior works independently of whether or not container-managed or bean-managed transaction demarcation has been used.
REMEMBER: propagation of a transaction-scoped persistence context Not linked to Entity Manager
The rule of thumb for persistence context propagation is that the persistence context propagates as the JTA transaction propagates. Therefore it is important to understand not only when transactions begin and end, but also when a business method expects to inherit the transaction context from another method and when doing so would be incorrect.
So if Employee bean calls Log bean and Log bean searches for emp entity then === if the Tx is same then PCxt is same so it can find. But if Log bean has REQUIRES_NEW then Tx is new for it and so PCxt is new and so it cannot find the bean.
Transaction association for extended persistence contexts is eager. In the case of containermanaged
transactions, as soon as a method call starts on the bean, the container automatically
associates the persistence context with the transaction. Likewise in the case of bean-managed
transactions; as soon as UserTransaction.begin() is invoked within a bean method, the container
intercepts the call and performs the same association.
Because a transaction-scoped entity manager will use an existing persistence context
associated with the transaction before it will create a new persistence context, it is possible to
share an extended persistence context with other transaction-scoped entity managers. So long
as the extended persistence context is propagated before any transaction-scoped entity managers
are accessed, the same extended persistence context will be shared by all components.
CRITICAL � COLLISION OF PCxt
A stateless session bean with a transactionscoped entity manager creates a new persistence context and then invokes a method on a stateful session bean with an extended persistence context. During the eager association of the
extended persistence context, the container will check to see if there is already an active persistence context. If there is, it must be the same as the extended persistence context that it is trying to associate, or an exception will be thrown.
the call into the stateful session beanwith Extended PCxt from Stateless with TxPCxt will fail. There can only be one active persistencecontext for a transaction.
Solution= REQUIRES_NEW for Stateful Tx. Would suspend existing Tx and Pcxt assos. And create new Tx and PCxt of SFSB.
Only if stateful Extended PCxt is first to be invoked from client = OK
Stateful session bean can safely create an application-managed entity manager, store it on the bean instance, and use it for persistence operations without having to worry about whether or not an active transaction already has a propagated persistence context.
When a stateful session bean with an extended persistence context creates another stateful session bean that also uses an extended persistence context, the child will inherit the parent�s persistence context. The EmployeeManager
bean inherits the persistence context from the DepartmentManager bean when it is injected into the DepartmentManager instance.
There is no limit to the number of application-managed persistence contexts that may be synchronized with a
transaction, but only one container-managed persistence context will ever be associated
An application-managed entity manager participates in a JTA transaction in one of two ways. If the persistence context is created inside the transaction, then the persistence provider will automatically synchronize the persistence context with the transaction. If the persistence context was created earlier (outside of a transaction or in a transaction that has since ended), the persistence context may be manually synchronized with the transaction by calling joinTransaction() on the EntityManager interface. Once synchronized, the persistence context will automatically be flushed when the transaction commits.
Because application-managed entity managers do not propagate, the only way to share managed entities with other components is to share the EntityManager instance � EM not thread safe while EMF is thread safe
application code must not call joinTransaction() on the same entity manager in multiple concurrent transactions
When the find() method is invoked on the entity manager, it will check the current transaction for an active persistence context only to determine that one does not exist. A new persistence context will be created starting with the find() call
~~~~~Here are some of my notes for Tx/PCxt:
When the find() method is invoked on the entity manager, it will check the current transaction for an active persistence context only to determine that one does not exist. A new persistence context will be created starting with the find() call
The rule of thumb for persistence context propagation is that the persistence context propagates as the JTA transaction propagates. Therefore it is important to understand not only when transactions begin and end, but also when a business method expects to inherit the transaction context from another method and when doing so would be incorrect.
==========================
Transaction association for extended persistence contexts is eager.
Transaction association for persistence contexts is lazy.
The stateful session bean is associated with a single extended persistence context that is created when the bean instance is created and closed when the bean instance is removed.
The transaction-scoped entity manager checks for an active persistence context and will find the extended persistence
context from the DepartmentManagerBean. It will then use this persistence context to execute the
operation. All of the managed entities from the extended persistence context become visible to
the transaction-scoped entity manager.
There can only be one active persistence context for a transaction. (Container managed PCxt)
When a stateful session bean with an extended persistence context creates another stateful session bean that also uses an extended persistence context, the child will inherit the parent�s persistence context.
There is no limit to the number of application-managed persistence contexts that may be synchronized with a
transaction, but only one container-managed persistence context will ever be associated
App Manage PCxt 2 ways Synch with CMPCxt:
1.If Tx started before � PCxt � then PCxt auto engaged with Tx
2.If Tx started after PCxt � then need to call joinTransaction() on EM
EM created not by DIJ but manually in a method. EMF = DIJ. Then need to call joinTransaction.
If we are creating EM then we need to close the EM as well !!
EMF thread safe. EM NOT thread safe
Cannot call jT() on same EM in multiple concurrent Tx.
Even if EM Closes = PCxt still synchronized when Tx commit.
Don�t use same entities in multiple PCxt. ! � Impt from data integrity
Know the API + Exception of the following classes:
UserTransaction, EntityTransaction, SessionContext, EJBContext , EMF and EM
CRITICAL : Difference between marking a Tx for rollback and rollback ( )
If op fails � in Etx then Containers MARKS it for rollback.
Marking for rollback != rollback Rollback only when rollback called !!
If marked and commit called = RollbackException . Avoid this by using getRollbackOnly to know status
Until Tx rollback � it is still active and Marked.
If rollback � then only db changes roll back � Object state NOT rollback. Need to keep a snapshot.
On Tx Rollback :
1. Db changes undone
2. PCxt cleared � all entities are detached,
3. If PCxt is Tx Scoped then Removed
What to use ? App Managed or Container Mgd? TxScope or EtxScoped?
Persist
If called outside Tx . If TxScoped EM = throws TxReqdEx
If App Mgd or Exd Tx then no action taken. Q formed till commit.
If ps id exists then EntityExistsExp
R/s
R/S Source = owner, Target= Inverse of R/S
Had we only added the employee to the collection
and not updated the other side of the relationship, nothing would have been persisted to
the database.
Container Mgd EM = DIJ or JNDI [ for JNDI @PCxt(name=�MyCxt�) public class Temp { }
~~~ Similarly EMF
App Mgd = Use EMF to create EM
After closing EMF cant use EM but should close EM
Container Mgd EM = JTA EM ONLY!!
Application Mgd EM = JTA or Resource Local
If ETx Commit fails then rollback Tx takes place auto.
For Tx scoped PCxt is based on life of Tx. Ends when Tx ends.And on ending all entities become detached.
=================================
Hth,
Shivani
[ July 31, 2007: Message edited by: Shivani Chandna ]