In several projects I needed a utility easy to use and that can be used by other programming languages like PHP, AS3, ..etc.
Scenario:
- A EJB3 container-managed transaction and persistence and the entities configured with JPA annotations (JBoss5.1 and Hibernate).
- Different client applications in Java and PHP, connected to the container by WebServices.
EntityCopy lets you copy an entity with JPA annotations by reflection and depth level set in real time. EntityCopy has the following levels of copy of an entity:
- NONE: Copy only the properties that are not associations.
- DEFAULT: Copy only the associations with FetchType.EAGER.
- FULL: Copy all the properties of the entity.
For example if we have the following entities:
@Entity public class Address { @Id String id; String street; ... } @Entity public class Person { @Id String id; String firstName; String lastName; @ManyToOne // By default FetchType.EAGER Person parent; @OneToMany // By default FetchType.LAZY Set<Address> addresses = new HashTable<Address>(); .. }
To make a copy of Person with associaiones configured with FetchType.EAGER (only the "parent" association):
Person entity = personDao.findByPk(pk); ... Person copy = EntityCopy.copy(Person entity, DeepCopy.DEFAULT);
If the second parameter is null, DeepCopyType.DEFAULT always be taken.
You can change the level of copy of a property defining it directly, for example, if you want a copy of Person but not the addresses list:
DeepCopy deepCopy = DeepCopy.createFull().add("addresses", DeepCopy.createNone()); Person copy = EntityCopy.copy(entity, deepCopy);
When DeepCopyType.NONE is assigned to a property, this property will not be copied.
EntityCopy avoids recursion between entities, to prevent infinite loops.
The following is a example of how to use EntityCopy with a web service.
TestServiceSEI.java
@WebService @SOAPBinding(style = SOAPBinding.Style.DOCUMENT) public interface TestServiceSEI { @WebMethod public List<Person> findAllPersons(@javax.jws.WebParam(name="deepCopy") DeepCopy deepCopy); }
TestServiceBean.java
@Stateless @WebService(endpointInterface="TestServiceSEI") @Remote(TestServiceSEI.class) public class TestServiceBean implements TestServiceSEI { @javax.persistence.PersistenceContext(unitName = "TestPU") protected javax.persistence.EntityManager entityManager; @javax.annotation.Resource protected javax.xml.ws.WebServiceContext wsCtx; public List<Person> findAllPersons(DeepCopy deepCopy) { Query query = this.getEntityManager().createQuery("select obj from Person obj"); List<Person> entities = query.getResultList(); if (wsCtx != null) { List<Person> results = new ArrayList<Person>(); for (Person entity : entities) { results.add(EntityCopy.copy(entity, deepCopy)); } return results; } return entities; } }
From a PHP client application:
test.php
<?php require_once "Cafeto/DeepCopy.php"; class TestService { protected $soapClient; public function __construct($wsdl) { $this->soapClient = new SoapClient($wsdl); } public function findAllPersons($deepCopy) { $ret = $this->soapClient->findAllPersons(array('deepCopy' => $deepCopy)); if (isset($ret->return)) if (is_array($ret->return)) return $ret->return; else return array($ret->return); else return array(); } } $service = new TestService("http://127.0.0.1:8080/test-service/TestService?wsdl"); $deepCopy = Cafeto_DeepCopy::createFull()->add("addresses", Cafeto_DeepCopy::createNone()); $persons = $service->findAllPersons($deepCopy);
You can download the jar file cafeto-entitycopy-0.5.0.jar and the PHP library cafeto-deepcopy.zip.
The source code repository is here.
You can also clone the project with Git by running:
$ git clone git://github.com/cafeto/cafeto-entitycopy
No comments:
Post a Comment