Solutions to IT problems

Solutions I found when learning new IT stuff

Posts Tagged ‘transaction

Creating a Framework for Chemical Structure Search – Part 7

leave a comment »

Series Overview

This is Part 7 – Service Layer of the “Creating a Framework for Chemical Structure Search“-Series.

Previous posts:

Follow-ups:

Introduction

In this article I will introduce the service layer of MoleculeDatabaseFramework. The service layer is responsible for transaction support and security.

Service for ChemicalStructure Entity

This service manages entities of type ChemicalStructure. This service is provided by the framework and should be used as-is. Any access of ChemicalStructures should be through this service. ChemicalStructureService contains the logic that make ChemicalStructures “immutable”. Quote from Part 5 of the series:

A ChemicalStructure is unique and immutable and managed by the framework. Users operate on ChemicalCompounds and not ChemicalStructures directly. Unique means if a new ChemicalCompound is saved, the framework checks if the ChemicalStructures in it already exist and if yes re-uses them. Immutable means that if a ChemicalCompound is updated and one of the ChemicalStructures has changed the framework will automatically check if the updated ChemicalStructure already exist and use it or create a new ChemicalStructure. The old one will remain unchanged!

In case a ChemicalStructure actually needs to be updated and the change should affect all ChemicalCompounds containing it the service has a separate method updateExistingStructure(structure) which requires the current user to have the role update_ChemicalStructure when Spring Security is enabled. In general this method should be restricted to Admins.

Below the source code for the two mentioned methods. Note that for brevity argument checks and logging statements were removed:

public T save(T structure) {
       
	T result = structureRepository.findByStructureKey(structure.getStructureKey());

	if (result == null) {
		// clear id (and createdBy and created) so that a new row is inserted
		structure.reset();

		return structureRepository.save(structure);
	} else {
		return structureRepository.save(result);
	}
}

@Override
public T updateExistingStructure(T structure){

	T result = structureRepository.findOne(structure.getId());

	if (result == null){
		throw new IllegalArgumentException("Given ChemicalStructure does not exist. It can't be updated.");
	}        
	return structureRepository.save(structure);
}

Services for ChemicalCompound and Containable

The services for ChemicalCompound and Containable are very similar. They consist of an interface which contains the security annotations and an implementation containing the @Transactional annotations for declarative transactions. They also offer methods with optional loading of lazy collections.

When a entity is saved, the service automatically sets the correct ChemicalStructures by either selecting an existing one from the database or creating a new one.
Also before the entity is passed to Hibernate, the method preSave(entity); is executed. This method is empty in the provided abstract services like ChemicalCompoundServiceImpl but can be overridden in subclasses. As example one could set all non-nullable properties to a default or a sequence value if it is null.

Below the source code of the save(entity) method of ChemicalCompoundServiceImpl for clarification:

public final T save(T compound) {
	logger.entry(compound);
	Preconditions.checkNotNull(compound);
	preSave(compound);
	if (compound.getCompositions() != null) {
		for (ChemicalCompoundComposition composition : compound.getCompositions()) {
			ChemicalStructure structure = composition.getChemicalStructure();
			ChemicalStructure result = chemicalStructureService.save(structure);
			composition.setChemicalStructure(result);
		}
	}
	//...snipped...
}

You need to create a service interface and an implementation for every ChemicalCompound and Containable implementation the application uses. The services must implement the getRepository(), checkUniqueness() and getExistingCompound() methods.

getRepository() must return the Spring-Data repository responsible for saving the entity of the same type as the current service is for.

checkUniqueness() must return if an entity is unique (does not violate any unique constraints) and if it is not unique it must return a Mapping of the violated constraint(all field names of constraint) and the offending value.

getExistingCompound() or getExistingContainable() respectively is called during import of SD-Files. The method must use the data from the SD-File (SdfRecord) to check if the current compound that is being imported already exists in the database. If it already exists it must return it, else it must return null.

Below an Example of such a Service implementation for RegistrationCompound entity:

RegistrationCompoundService UML

Note that Java Generics are not shown in above diagram hence in source code:

public interface RegistrationCompoundService extends ChemicalCompoundService<RegistrationCompound> {
	//...snipped...
}

public class RegistrationCompoundServiceImpl extends ChemicalCompoundServiceImpl<RegistrationCompound>
        implements RegistrationCompoundService {
	//...snipped...
}

Please see the MoleculeDatabaseFramework Tutorial for further information on how to implement such services.

ChemicalCompoundContainerService

This service manages entities of type ChemicalCompoundContainer. The main difference to services for ChemicalCompound and Containable is that an application should only have 1 implementation of ChemicalCompoundContainer and hence only 1 such service. The service can be used out-of-the-box or in some cases must be extended as example when the ChemicalCompoundContainer implementation adds additional unique constraints, checkUniqueness() and getExistingContainer() must be overridden.

Also ChemicalCompoundContainerService has some special considerations in terms of the Spring-Security integration.

Please see the MoleculeDatabaseFramework Tutorial for further information on how to implement such a service.

Advertisements

Written by kienerj

May 8, 2013 at 08:06