- Standard entity interfaces

- EntityLifecycleListener
- TimeProvider, SecurityProvider
This commit is contained in:
Konstantin Krivopustov 2008-11-12 12:49:55 +00:00
parent 672950449b
commit aa16900e50
20 changed files with 368 additions and 48 deletions

View File

@ -2,6 +2,11 @@ create table SYS_SERVER (
ID varchar(36),
CREATE_TS timestamp,
CREATED_BY varchar(20),
VERSION integer,
UPDATE_TS timestamp,
UPDATED_BY varchar(20),
IS_DELETED smallint,
DELETED_BY varchar(20),
NAME varchar(255),
ADDRESS varchar(255),
IS_RUNNING smallint,

View File

@ -3,8 +3,11 @@
<persistence-unit name="cuba" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<class>com.haulmont.cuba.core.entity.BaseUuidEntity</class>
<class>com.haulmont.cuba.core.entity.StandardEntity</class>
<class>com.haulmont.cuba.core.entity.Server</class>
<properties>
<property name="openjpa.Log" value="log4j"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=72"/>

View File

@ -13,6 +13,4 @@ public class CubaProperties
{
public static final String PERSISTENCE_XML = "cuba.PersistenceXml";
public static final String PERSISTENCE_UNIT = "cuba.PersistenceUnit";
public static final int LOGIN_FIELD_LEN = 20;
}

View File

@ -13,6 +13,8 @@ import com.haulmont.cuba.core.impl.ManagedPersistenceProvider;
public abstract class PersistenceProvider
{
public static final int LOGIN_FIELD_LEN = 20;
private static PersistenceProvider instance;
private static PersistenceProvider getInstance() {

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 11.11.2008 18:27:17
*
* $Id$
*/
package com.haulmont.cuba.core;
import com.haulmont.cuba.core.impl.SecurityProviderImpl;
public abstract class SecurityProvider
{
private static SecurityProvider instance;
private static SecurityProvider getInstance() {
if (instance == null) {
instance = new SecurityProviderImpl();
}
return instance;
}
public static String currentUserLogin() {
return getInstance().__currentUserLogin();
}
protected abstract String __currentUserLogin();
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 11.11.2008 14:29:14
*
* $Id$
*/
package com.haulmont.cuba.core;
import com.haulmont.cuba.core.impl.TimeProviderImpl;
import java.util.Date;
public abstract class TimeProvider
{
private static TimeProvider instance;
private static TimeProvider getInstance() {
if (instance == null) {
instance = new TimeProviderImpl();
}
return instance;
}
public static Date currentTimestamp() {
return getInstance().__currentTimestamp();
}
protected abstract Date __currentTimestamp();
}

View File

@ -9,7 +9,7 @@
*/
package com.haulmont.cuba.core.entity;
import com.haulmont.cuba.core.CubaProperties;
import com.haulmont.cuba.core.PersistenceProvider;
import javax.persistence.Column;
import javax.persistence.Id;
@ -27,7 +27,7 @@ public class BaseLongIdEntity implements BaseEntity<Long>
@Column(name = "CREATE_TS")
private Date createTs;
@Column(name = "CREATED_BY", length = CubaProperties.LOGIN_FIELD_LEN)
@Column(name = "CREATED_BY", length = PersistenceProvider.LOGIN_FIELD_LEN)
private String createdBy;
public Long getId() {

View File

@ -9,20 +9,16 @@
*/
package com.haulmont.cuba.core.entity;
import com.haulmont.cuba.core.PersistenceProvider;
import org.apache.openjpa.persistence.Persistent;
import javax.persistence.MappedSuperclass;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import java.util.UUID;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import java.util.Date;
import com.haulmont.cuba.core.CubaProperties;
import com.haulmont.cuba.core.persistence.BaseEntityListener;
import java.util.UUID;
@MappedSuperclass
@EntityListeners({BaseEntityListener.class})
public class BaseUuidEntity implements BaseEntity<UUID>
{
@Id
@ -33,7 +29,7 @@ public class BaseUuidEntity implements BaseEntity<UUID>
@Column(name = "CREATE_TS")
private Date createTs;
@Column(name = "CREATED_BY", length = CubaProperties.LOGIN_FIELD_LEN)
@Column(name = "CREATED_BY", length = PersistenceProvider.LOGIN_FIELD_LEN)
private String createdBy;
public BaseUuidEntity() {

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 12.11.2008 12:29:58
*
* $Id$
*/
package com.haulmont.cuba.core.entity;
public interface DeleteDeferred extends Updatable
{
Boolean isDeleted();
void setDeleted(Boolean deleted);
String getDeletedBy();
void setDeletedBy(String deletedBy);
}

View File

@ -9,15 +9,14 @@
*/
package com.haulmont.cuba.core.entity;
import com.haulmont.cuba.core.entity.BaseEntity;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
@Entity
@Table(name = "SYS_SERVER")
public class Server extends BaseUuidEntity
public class Server extends StandardEntity
{
@Column(name = "NAME")
private String name;

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 11.11.2008 18:32:18
*
* $Id$
*/
package com.haulmont.cuba.core.entity;
import com.haulmont.cuba.core.PersistenceProvider;
import javax.persistence.MappedSuperclass;
import javax.persistence.Column;
import javax.persistence.Version;
import java.util.Date;
@MappedSuperclass
public class StandardEntity
extends BaseUuidEntity
implements Versioned, Updatable, DeleteDeferred
{
@Version
@Column(name = "VERSION")
private Integer version;
@Column(name = "UPDATE_TS")
private Date updateTs;
@Column(name = "UPDATED_BY", length = PersistenceProvider.LOGIN_FIELD_LEN)
private String updatedBy;
@Column(name = "IS_DELETED")
private Boolean deleted = false;
@Column(name = "DELETED_BY", length = PersistenceProvider.LOGIN_FIELD_LEN)
private String deletedBy;
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public Date getUpdateTs() {
return updateTs;
}
public void setUpdateTs(Date updateTs) {
this.updateTs = updateTs;
}
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}
public Boolean isDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
public String getDeletedBy() {
return deletedBy;
}
public void setDeletedBy(String deletedBy) {
this.deletedBy = deletedBy;
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 11.11.2008 18:25:30
*
* $Id$
*/
package com.haulmont.cuba.core.entity;
import java.util.Date;
public interface Updatable
{
Date getUpdateTs();
void setUpdateTs(Date updateTs);
String getUpdatedBy();
void setUpdatedBy(String updatedBy);
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 12.11.2008 12:23:01
*
* $Id$
*/
package com.haulmont.cuba.core.entity;
public interface Versioned
{
Integer getVersion();
void setVersion(Integer version);
}

View File

@ -11,7 +11,9 @@ package com.haulmont.cuba.core.impl;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import com.haulmont.cuba.core.EntityManagerAdapter;
import com.haulmont.cuba.core.SecurityProvider;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.cuba.core.entity.DeleteDeferred;
public class EntityManagerAdapterImpl implements EntityManagerAdapter
{
@ -30,7 +32,13 @@ public class EntityManagerAdapterImpl implements EntityManagerAdapter
}
public void remove(BaseEntity entity) {
jpaEm.remove(entity);
if (entity instanceof DeleteDeferred) {
((DeleteDeferred) entity).setDeleted(true);
((DeleteDeferred) entity).setDeletedBy(SecurityProvider.currentUserLogin());
}
else {
jpaEm.remove(entity);
}
}
public <T extends BaseEntity> T find(Class<T> clazz, Object key) {

View File

@ -14,6 +14,8 @@ import org.apache.commons.logging.LogFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import javax.naming.Context;
import javax.naming.NamingException;
@ -27,6 +29,7 @@ import com.haulmont.cuba.core.PersistenceProvider;
import com.haulmont.cuba.core.EntityManagerFactoryAdapter;
import com.haulmont.cuba.core.EntityManagerAdapter;
import com.haulmont.cuba.core.CubaProperties;
import com.haulmont.cuba.core.persistence.EntityLifecycleListener;
public class ManagedPersistenceProvider extends PersistenceProvider
{
@ -63,6 +66,7 @@ public class ManagedPersistenceProvider extends PersistenceProvider
OpenJPAEntityManagerFactory jpaFactory =
OpenJPAPersistence.createEntityManagerFactory(unitName, xmlPath);
initJpaFactory(jpaFactory);
EntityManagerFactoryAdapter emf = new EntityManagerFactoryAdapterImpl(jpaFactory);
try {
@ -81,6 +85,13 @@ public class ManagedPersistenceProvider extends PersistenceProvider
}
}
private void initJpaFactory(OpenJPAEntityManagerFactory jpaFactory) {
((OpenJPAEntityManagerFactorySPI) jpaFactory).addLifecycleListener(
new EntityLifecycleListener(),
null
);
}
protected EntityManagerAdapter __getEntityManager() {
EntityManagerAdapterImpl em;
try {

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 11.11.2008 18:29:38
*
* $Id$
*/
package com.haulmont.cuba.core.impl;
import com.haulmont.cuba.core.SecurityProvider;
public class SecurityProviderImpl extends SecurityProvider
{
protected String __currentUserLogin() {
return "admin";
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 11.11.2008 16:14:49
*
* $Id$
*/
package com.haulmont.cuba.core.impl;
import com.haulmont.cuba.core.TimeProvider;
import java.util.Date;
public class TimeProviderImpl extends TimeProvider
{
protected Date __currentTimestamp() {
return new Date();
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 10.11.2008 16:33:43
*
* $Id$
*/
package com.haulmont.cuba.core.persistence;
import com.haulmont.cuba.core.entity.BaseEntity;
import javax.persistence.PrePersist;
import java.util.Date;
public class BaseEntityListener
{
@PrePersist
void onCreate(Object obj) {
if (obj instanceof BaseEntity) {
((BaseEntity) obj).setCreatedBy("admin");
((BaseEntity) obj).setCreateTs(new Date());
}
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 11.11.2008 18:14:37
*
* $Id$
*/
package com.haulmont.cuba.core.persistence;
import com.haulmont.cuba.core.SecurityProvider;
import com.haulmont.cuba.core.TimeProvider;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.cuba.core.entity.Updatable;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.event.AbstractLifecycleListener;
import org.apache.openjpa.event.LifecycleEvent;
import java.util.Date;
public class EntityLifecycleListener extends AbstractLifecycleListener
{
public void beforePersist(LifecycleEvent event) {
if ((event.getSource() instanceof BaseEntity)) {
__beforePersist((BaseEntity) event.getSource());
}
}
public void beforeStore(LifecycleEvent event) {
PersistenceCapable pc = (PersistenceCapable) event.getSource();
if (!pc.pcIsNew() && (event.getSource() instanceof Updatable)) {
__beforeUpdate((Updatable) event.getSource());
}
}
private void __beforePersist(BaseEntity entity) {
entity.setCreatedBy(SecurityProvider.currentUserLogin());
Date ts = TimeProvider.currentTimestamp();
entity.setCreateTs(ts);
if (entity instanceof Updatable) {
((Updatable) entity).setUpdateTs(TimeProvider.currentTimestamp());
}
}
private void __beforeUpdate(Updatable entity) {
String user = SecurityProvider.currentUserLogin();
entity.setUpdatedBy(user);
entity.setUpdateTs(TimeProvider.currentTimestamp());
}
}

View File

@ -36,9 +36,32 @@ public class PersistenceTest extends CubaTestCase
throw new RuntimeException(e);
}
EntityManagerAdapter em = PersistenceProvider.getEntityManager();
Server server = em.find(Server.class, id);
assertEquals(id, server.getId());
beginTran();
try {
EntityManagerAdapter em = PersistenceProvider.getEntityManager();
Server server = em.find(Server.class, id);
assertEquals(id, server.getId());
server.setAddress("222");
commitTran();
} catch (Exception e) {
rollbackTran();
throw new RuntimeException(e);
}
beginTran();
try {
EntityManagerAdapter em = PersistenceProvider.getEntityManager();
Server server = em.find(Server.class, id);
assertEquals(id, server.getId());
em.remove(server);
commitTran();
} catch (Exception e) {
rollbackTran();
throw new RuntimeException(e);
}
}
private void beginTran() {