I just cleared the SCBCD. JavaRanch is great place! I found a lot of useful threads here that helped me to clear some of my doubts. The wall of fame is extremely useful and my duty is to share my preparation experience.
1. EJB3 in Action (without JPA)
2. Enterprise JavaBeans 3.0 (only JPA)
3. Mikalai Zaikin guide – Mikalai, perfect work!
4.
EJB restrictions
5. Last Minute Notes (Raghavendra Balgi) – Raghavendra very compact, very good!
6. 3 days tests (Yes, I had tight preparation time)
This was my preparation path but now after all I think that there is a more optimal way:
1. Enterprise JavaBeans 3.0 (The best book for certification, for initial study maybe better is EJB3 In Action)
2. Mikalai Zaikin guide
3.
EJB restrictions
4. Last Minute Notes (Raghavendra Balgi)
5. I complemented the Raghavendra's notes (The document is at the bottom of this post)
6. At least 2 weeks tests for top result (Maybe enthuware is the best simulator)
Next
SCEA ...
---
BorisV5
Here are the complementary notes:
@MessageDriven(activationConfig={@ActvivationConfigProperty(propertyName="",propertyValue=""),..})
Example Property Names - destinationType
acknowledgeMode
messageSelector
subscriptionDurability
- acknowledgement is explicit for CMT. For BMT if set is done regardless transaction
- Auto-Acknowledge (container should tell the provideer about the delivery immediately)
- Dups-ok-acknowledge (container can tell the provideer anytime after message has been dispatched to a instance)
- durability is set only for Topics / for Queu it is explicit
Unspecified transaction & security context (spec 4.3.4 also 13.6.5) it is vendor specific
- All callbacks (PostConstruct, PreDestroy, PrePassivate, PostActivate). (The interceptor ArroundInvoke is not included)
- TransactionSynchronization.afterCompletion
(Spec: 4.3.14. The PostConstruct and PreDestroy methods are not controlled by a transaction attribute because
handling rollbacks in these methods would greatly complicate the session instance’s state diagram)
SAME transaction context as the business method
- ArroundInvoke
- SessionSynchronization.afterBegin
- SessionSynchronization.beforeCompletion
Enterprise Bean
- Can't be listen to or accept connections on a socket, BUT can be a client of socked
If needed to throw system exception:
- EJB3 throw EJBException if remote client view
- EJB2.x throw java.rmi.RemoteException if remote client view
- EJB2.x throw EJBException if local client view
- WebService endpoint interface throw java.rmi.RemoteException
SessionBean/Message-Driven
Class
- public, not final or abstract. Top level class (not nested).
Methods
- must be declared as public (no final or static)
- must not start with “ejb”
EJB 2.x interfaces
EJBHome from EJBContext - remote home interface (remote) *
EJBLocalHome from EJBContext - local home interface (remote same server)
EJBObject from SessionContext - object (local) *
EJBLocalObject from SessionContext - local object (local same server)
SessionBean --- - implemented from EJB 2.x
Logically similar methods:
- Timeout method (@Timeout or implements TimedObject.ejbTimeout). Timer manipulated from EJBContext.TimerService
- OnMessage (implements MessageListener). MDB
Environment entry values type:
String and Integer only
- getCallerPrincipal() called from onMessage or ejbTimout throws IllegalSatateException
- EJBContext.get/setRollbackOnly called from bean with BMT throws IllegalSatateException
- get/setRollbackOnly called out of transaction throws IllegalSatateException
- After close on EntityManager any method call causes
IllegalStateException, except getTransaction and isOpen
All modifiers apply (public, private, protected, or package) for:
- Lifecycle callback interceptor methods (including AroundInvoke)
- Injected Field/Method
- Timeout method
EntityManager
Unless you are using an extended persistence context, committing or rolling back also ends
the persistence context.
Persistence Context Propagation only from Local intefaces (propagation inside JTA transaction)
Transaction Scoped = TS
Extended = EX
-> = call
EX -> EX = context is propagated
EX -> TS = EX context is propagated
TS -> EX = throws EJBException
Entity
- class (public)
- class' no-arg constructor (public OR protected)
- property accessor methods (public OR protected)
- Instance variables (non public)
- Both abstract and concrete classes can be entities
- The state of the entity is available ONLY through the entity's ACCESSOR METHODS
- annotations MUST NOT be applied to the setter methods (only to getters/fields)
Inheritance strategies (@Inheritance(strategy="xxx")):
- SINGLE_TABLE (@DiscriminatorColumn, @DiscriminatorValue for each sub-class)
- TABLE_PER_CLASS (optional support)
- JOINED - "Table per Subclass" (@PrimaryKeyJoinColumn(name="EMP_PK"))
Primary Keys
*Id generators
@GeneratedValue(strategy=GenerationType.xxx, generator="generator_name")
- AUTO
- IDENTITY - SOME databases support a primary key identity column used from this strategy
- SEQUENCE - @SequenceGenerator(name="generator_name", sequenceName="Emp_Seq")
- TABLE (@TableGenerator) - many table generators in this table, pre-allocate a block of IDs
*Composite Keys
- @IdClass(CustomerPK.class) on class - use @Id for each property for the composite PK
- @EmbeddedId on the id property - annotate the composite class with @Embeddable
- Embedded Objects - use @Embedded and @Embeddable
- Multitable mappings. Two or more tables for one entity
@SecondaryTable(name="ADDRESS_TABLE",
pkJoinColumns={
@PrimaryKeyJoinColumn(name="ADDRESS_ID")})
<entity class="..." metadata-complete="true"> ignors any class' metadata (annotations)
entity: remove -> merge = IllegalArgumentException
Query
positional parameters - ? ex: "from Customer c where c.firstName=?1 and c.lastName=?2"
named parameter - : ex: "from Customer c where c.firstName=:first and c.lastName=:last"
One To Many unidirectional relationship!!!
- With join table
@OneToMany(cascade={CascadeType.ALL})
@JoinTable(name="CUSTOMER_PHONE"),
joinColumns={@JoinColumn(name="CUSTOMER_ID")},
inverseJoinColumns={@JoinColumn(name="PHONE_ID")})
public Collection<Phone> getPhoneNumbers( ){}
- With join column on the reverse side
@OneToMany(cascade={CascadeType.ALL})
@JoinColumn(name="CUSTOMER_ID") // FK on Phone table
public Collection<Phone> getPhoneNumbers( ){}