Showing posts with label BizSutra. Show all posts
Showing posts with label BizSutra. Show all posts

Sunday, December 17, 2006

Smart Key Generator ejb3


Java Persistence provides facility for auto-generation of primary keys. But limited to integer datatype. Further there is no convenient way to access these generated values. Its often needed that the primary key is a combination of identifiable data. Such keys are also known as Smart Keys.
Smart Keys also need automatic serial number generation.
Following solution uses HiLo sequence generation algorithm.

The solution contains one Stateless Session Bean and a Singleton. Additionally it consists an Entity (JPA)


package jkook.vetan.utils;
/*
* HrSequenceFacade.java
*/
@Stateless
public class HrSequenceFacade implements HrSequenceFacadeLocal, HrSequenceFacadeRemote {


@PersistenceContext
private EntityManager em;

private UIDDispenser uiddispenser;
private static final Logger log = Logger.getLogger(HrSequence.class.getName());

/** Creates a new instance of HrSequenceFacade */
public HrSequenceFacade() {

}

public void create(HrSequence hrSequence) {
em.persist(hrSequence);
}


public void edit(HrSequence hrSequence) {
em.merge(hrSequence);
em.flush();
log.info("HrSequence Updated");

}

public void destroy(HrSequence hrSequence) {
em.merge(hrSequence);
em.remove(hrSequence);
}

public HrSequence find(Object pk) {
return (HrSequence) em.find(HrSequence.class, pk);
}

public List findAll() {
return em.createQuery("select object(o) from HrSequence as o").getResultList();
}

/*
if dispenser is null
create new dispenser
getnextHi from dispenser

*/

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Integer getNextID(String entityname) {
log.info(" getNextId called");
uiddispenser = UIDDispenser.getDispenser(em);
return uiddispenser.getNextID(entityname,em);
}

public Integer getCount() {
Query q = em.createQuery("select count(o) from HrSequence as o ");
Long count = (Long)q.getSingleResult();
if(count != null){
return count.intValue();
}
return null;
}

public Integer getCurrentID(String entityname) {
uiddispenser = UIDDispenser.getDispenser(em);
return uiddispenser.getCurrentID(entityname);
}
}



/*
* UIDDispenser.java
*
*/

package jkook.vetan.utils;

public class UIDDispenser {


private static UIDDispenser uiddispenser;
private Map allentries;
private static final byte maxLo = 25;
static Logger log = Logger.getLogger(UIDDispenser.class.getName());
/** Creates a new instance of UIDDispenser */
private UIDDispenser() {

}

private UIDDispenser(EntityManager em){
// populate all entries
Iterator i =
em.createQuery("select object(o) from HrSequence as o")
.getResultList()
.iterator();
// for large database initiate the hashmap with count of HrSequence
allentries = new HashMap();
while(i.hasNext()){
HrSequence hs = i.next();
hs.setNextHi(hs.getNextHi()+maxLo);
allentries.put(hs.getEntityname(),hs);
System.err.println(" enityties +++ "+hs.getEntityname());
}

}

public static synchronized UIDDispenser getDispenser( EntityManager em) {
if (uiddispenser == null)
return new UIDDispenser(em);
return uiddispenser;

}

/*
* get nextLo
if lo > max_lo getnext HI
set lo=0
return HI+Lo
*
*
*/
public synchronized Integer getNextID(String entityname, EntityManager em){

HrSequence hs = allentries.get(entityname);
if(hs.getLo() >=maxLo){
log.fine(" LO Val is > maxLo " +hs.getLo() + " maxLo is " + maxLo );
hs.setNextHi(hs.getNextHi()+maxLo);
em.merge(hs);
byte b=0;
hs.setLo(b);
log.fine("Updated HI_VAL");
}
return hs.getNextHi()+ hs.getNextLo();
}

public Integer getCurrentID(String entityname){
HrSequence hs = allentries.get(entityname);
return hs.getNextHi()+ hs.getLo();
}
}

Usage :
@EJB HrSequenceFacade hrSequenceFacade
{
....
....
// start of smart key generation
// smartkey part1
// smartkey part2
Integer nextSerial = hrSequenceFacade.getNextID("NameityOfTheEnt")
// primaryKey = smartkeypart1 + part2 + nextSerial



Ref : Using Primary Keys with Java Persistence

Friday, December 01, 2006

Choosing Primary Keys

Exert from OracleFAQ

  1. The candidate key must be unique within its domain (the entity it represents, and beyond, if you also intend to
    access external entities).
  2. The candidate key can not hold NULL values (NULL is not zero. Zero is a number. NULL is 'nonexistent value').
  3. The candidate key can never change. It must hold the same value for a given occurrence of an entity for the lifetime of that entity.

BizSutra adds

PrimaryKey has to be HUMAN Readable

There are many strategies for identifying a Primary Key. With advancement of OOP the debate for surrogate keys has elongated. The fact remains that the strength of Object Oriented Programming is readability of the code. This capability has to be extended to persistence layer. Using surrogate keys defeats the above capability. Having Mnemonic code in foreign key fields is a good practice. Gurus suggest is 8.

Data Live Longer Than the Logic Accessing the Data

Tuesday, November 07, 2006

Jkook Blue Prints for JAVA

Jkook Blue Prints for JAVA(BizSutra)
The Introduction
Software development has been challenging as ever. The irony is it has been repetitive for most of us. Over the years I have developed many software products and written heaps of code. Lets take a case of a simple 'Ledger Application' . The first ledger application I have written is in C. Later learnt that a more stable version in COBOL exists in mainframe world. Next a database bug bit me. The Dbase. Then went on to write it in FoxPro. Then came the Open Systems . Had to write it again in Visual Basic (plus oracle). Long Before which i had the taste of technologies like magic and power builder.
Not very long ago I did it again using LAMP.
Welcome to JAVA. History repeated using Servlets. Later with glorified technologies like jsp, struts ...etc . Today i am writing in EJB 2 and Looking forward to write it in ejb3.

The hope the reader of this blog appreciates that the above memoir is not about a specific product. Its about a group of functional requirements which are being solved using different coding languages and techniques. A closer observation reveals that most of these requirements have never changed. And are not going to change in the future. But irony is most of the programmers approach has been consistent. The 'boringly repetitive approach' in question is freshly design, freshly code, freshly gather requirements, use same old faulty patterns. How many times have to coded user authentication,auditing ?

How do we avoid having to code the same set of functional requirements over all again and again?
This is precisely what this BizSutra for Java is going to provide. Wait a min what about those latest technologies and frame-works aren't they supposed to make your life easier?
Yes they do.But does not solve the problem discussed here. Technology is just one piece of this puzzle. Frame-works provide solutions in isolation. We need an integrated solution addressing most of the business requirements.
Let me explain with an example
Auditing is most common requirement. Say we use ejb for auditing. Then what about undo/redo support. Where is does Authentication/Authorization happen ? Most of the frame works provide solutions which work for both requirements. But in isolation. Each of them has to be coded separately and integrated. The BizSutra proposes a single implementation for both the requirements. The challenge is to identify all such common requirements and bundle them as a single implementation.

Business Application Defined
BizSutras
does not attempt to solve all problems. It should be used to develop Business Applications. Typical Business Applications are Accounting, Banking, Inventory Management, Invoice. These types of applications share a common set of functional requirements ie,
[Authentication , Authorization, Audit, Undo/Redo, Persistence, Maker-Checker, One or Two business work-flows, Bulk Import and Export]

The Deliverable :
A comprehensive set of business functionality.
The technology oriented frame-works provide solutions for a specific set of technical problems.(for example scope of Hibernate is persistence , Scope of Struts is MVC). These capabilities are exposed as services or an api. One has to consume these services appropriately to build a Business Application.
BizSutras provides integrated implementation for all the business function discussed above.