vdenotaris
vdenotaris

Reputation: 13637

CRUD operations by managing foreign key dependencies with Hibernate

I've two tables, Organization and OrganizationReferent (that has a column as foreign key) as follows:

DB schema

By using Hibernate as ORM (in a JPA-compliant project), I've obtained entities ad shown here.
I should manage CRUD operations by using Java EE 6-based Data Access Objects (DAOs).

Both OrganizationDAO and OrganizationReferentDAO extends a GenericDAO Implementation that provides a create method as follows:

@Override
public EntityClass create(EntityClass entity) throws IllegalStateException, PersistenceException, ConstraintViolationException
{
    entityManager.persist(entity);
    entityManager.flush();
    return entity;
}

Now, I defined a Wrapper class with the aim to manage CRUD operations that involve the two defined tables:

@Inject private OrganizationDAO organizationDAO;
@Inject private OrganizationReferentDAO organizationReferentDAO;

public final Organization createOrganization(final Organization organization) throws AlreadyExistsException, BadRequestException, DALException {
  assert(organization != null);
  organizationDAO.create(organization);
}, 

public final OrganizationReferent createOrganizationReferent(final Long organizationId, final OrganizationReferent organizationReferent) throws ConstraintViolationException, AlreadyExistsException, BadRequestException, DALException {
  assert(organizationId != null);
  assert(organizationReferent != null);
  try {
    organizationReferent.setOrganization(organizationDAO.findById(organizationId));
    organizationReferentDAO.create(organizationReferent);
  } catch (NotFoundException e) {
    throw new ConstraintViolationException();
  }
}
  1. Is this approach right or should I use something different?

  2. For the given cardinalities, should I force creations or edit the schema (for instance, changing from (1,*) to (0,*))?

Upvotes: 1

Views: 1215

Answers (1)

przemek hertel
przemek hertel

Reputation: 4004

ad 1)

In my opinion your approach is right. One important thing is how you manage your transactions. One common pattern is to have service-layer classes that have injected many DAOs and methods in such service class is marked as @Transactional but DAO methods are never marked @Transactional.

Such service class perform complex operations on different objects - that is why it can operate on different DAOs. Your Wrapper class looks like such service-layer class.

Second thing is using entityManager.flush() is not recommended in such place. Forcing flush after each entityManger.persist() break performace if there are more complicated tasks. You should skip your flush() call - flush() will be automatically called just before transaction commit.

ad 2)

I suggest to force creating 1 child record to fit (1,*) requirement...

Upvotes: 1

Related Questions