diff -r 6a7b86469daa modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java	Wed May 15 08:18:19 2013 +0000
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java	Tue Jun 18 13:20:28 2013 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2012 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2013 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -474,6 +474,12 @@
     // or uses the display column to display that in the grid
     Property useProperty = property;
     String useFieldName = fieldName.replace(DalUtil.FIELDSEPARATOR, DalUtil.DOT);
+
+    if (useProperty.isComputedColumn()) {
+      // Computed columns are not directly accessed but through _computedColumns proxy
+      useFieldName = Entity.COMPUTED_COLUMNS_PROXY_PROPERTY + DalUtil.DOT + useFieldName;
+    }
+
     if (properties.size() >= 2) {
       final Property refProperty = properties.get(properties.size() - 2);
       if (refProperty.getDomainType() instanceof TableDomainType) {
@@ -1174,6 +1180,13 @@
         }
       }
     } else {
+      Entity searchEntity = getEntity();
+      Property property = searchEntity.getProperty(localOrderBy);
+      if (property != null && property.isComputedColumn()) {
+        // Computed columns are accessed through proxy
+        localOrderBy = Entity.COMPUTED_COLUMNS_PROXY_PROPERTY + DalUtil.DOT + localOrderBy;
+      }
+
       paths.add(localOrderBy);
     }
 
diff -r 6a7b86469daa modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonToDataConverter.java
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonToDataConverter.java	Wed May 15 08:18:19 2013 +0000
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonToDataConverter.java	Tue Jun 18 13:20:28 2013 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2013 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -766,6 +766,7 @@
     // do not change not updatable properties
     // Updatable is a UI concept
     // doNotHandleThisProperty |= !obObject.isNewOBObject() && !property.isUpdatable();
+    doNotHandleThisProperty |= property.isProxy();
     return doNotHandleThisProperty;
   }
 
diff -r 6a7b86469daa src/org/openbravo/base/gen/GenerateEntitiesTask.java
--- a/src/org/openbravo/base/gen/GenerateEntitiesTask.java	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/base/gen/GenerateEntitiesTask.java	Tue Jun 18 13:20:28 2013 +0200
@@ -36,6 +36,7 @@
 import org.openbravo.base.exception.OBException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
+import org.openbravo.base.model.Property;
 import org.openbravo.base.session.OBPropertiesProvider;
 
 import freemarker.template.Configuration;
@@ -124,26 +125,77 @@
     File ftlFile = new File(getBasePath(), ftlFilename);
     freemarker.template.Template template = createTemplateImplementation(ftlFile);
 
+    // template for computed columns entities
+    String ftlComputedFilename = "org/openbravo/base/gen/entityComputedColumns.ftl";
+    File ftlComputedFile = new File(getBasePath(), ftlComputedFilename);
+    freemarker.template.Template templateComputed = createTemplateImplementation(ftlComputedFile);
+
     // process template & write file for each entity
     List<Entity> entities = ModelProvider.getInstance().getModel();
     for (Entity entity : entities) {
-      String classfileName = entity.getClassName().replaceAll("\\.", "/") + ".java";
-      log.debug("Generating file: " + classfileName);
-      File outFile = new File(srcGenPath, classfileName);
-      new File(outFile.getParent()).mkdirs();
+      File outFile;
+      String classfileName;
+      Writer outWriter = null;
 
-      Writer outWriter;
-      try {
-        outWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),
-            "UTF-8"));
-        Map<String, Object> data = new HashMap<String, Object>();
+      if (!entity.isVirtualEntity()) {
+        classfileName = entity.getClassName().replaceAll("\\.", "/") + ".java";
+        log.debug("Generating file: " + classfileName);
+        outFile = new File(srcGenPath, classfileName);
+        new File(outFile.getParent()).mkdirs();
 
-        data.put("entity", entity);
-        processTemplate(template, data, outWriter);
-      } catch (IOException e) {
-        log.error("Error generating file: " + classfileName, e);
+        outWriter = null;
+        try {
+          outWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),
+              "UTF-8"));
+          Map<String, Object> data = new HashMap<String, Object>();
+
+          data.put("entity", entity);
+          processTemplate(template, data, outWriter);
+        } catch (IOException e) {
+          log.error("Error generating file: " + classfileName, e);
+        } finally {
+          if (outWriter != null) {
+            try {
+              outWriter.close();
+            } catch (IOException ignore) {
+            }
+          }
+        }
       }
 
+      if (entity.hasComputedColumns()) {
+        classfileName = entity.getPackageName().replaceAll("\\.", "/") + "/"
+            + entity.getSimpleClassName() + Entity.COMPUTED_COLUMNS_CLASS_APPENDIX + ".java";
+        log.debug("Generating file: " + classfileName);
+        outFile = new File(srcGenPath, classfileName);
+        new File(outFile.getParent()).mkdirs();
+        outWriter = null;
+        try {
+          outWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),
+              "UTF-8"));
+          Map<String, Object> data = new HashMap<String, Object>();
+          data.put("entity", entity);
+          List<Property> properties = entity.getComputedColumnProperties();
+          properties.add(entity.getProperty("client"));
+          properties.add(entity.getProperty("organization"));
+          data.put("properties", properties);
+          List<String> imports = entity.getJavaImports(properties);
+          imports.remove("import org.openbravo.base.structure.ActiveEnabled;");
+          imports.remove("import org.openbravo.base.structure.Traceable;");
+          data.put("javaImports", imports);
+          processTemplate(templateComputed, data, outWriter);
+        } catch (IOException e) {
+          log.error("Error generating file: " + classfileName, e);
+        } finally {
+          if (outWriter != null) {
+            try {
+              outWriter.close();
+            } catch (IOException ignore) {
+            }
+          }
+
+        }
+      }
     }
     log.info("Generated " + entities.size() + " entities");
   }
diff -r 6a7b86469daa src/org/openbravo/base/gen/entity.ftl
--- a/src/org/openbravo/base/gen/entity.ftl	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/base/gen/entity.ftl	Tue Jun 18 13:20:28 2013 +0200
@@ -26,7 +26,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2008-2011 Openbravo SLU
+ * All portions are Copyright (C) 2008-2013 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -46,12 +46,23 @@
     public static final String TABLE_NAME = "${entity.tableName}";
     public static final String ENTITY_NAME = "${entity.name}";
     <#list entity.properties as p>
+    <#if !p.computedColumn>
     public static final String PROPERTY_${p.name?upper_case} = "${p.name}";
+    </#if>
     </#list>
+    
+    <#if entity.hasComputedColumns()>
+    // Computed columns properties, these properties cannot be directly accessed, they need
+    // to be read through _commputedColumns proxy. They cannot be directly used in HQL, OBQuery
+    // nor OBCriteria. 
+    <#list entity.computedColumnProperties as p>
+    public static final String COMPUTED_COLUMN_${p.name?upper_case} = "${p.name}";
+    </#list>
+    </#if>
 
     public ${entity.simpleClassName}() {
     <#list entity.properties as p>
-        <#if p.hasDefaultValue()>
+        <#if p.hasDefaultValue() && !p.computedColumn>
         setDefaultValue(PROPERTY_${p.name?upper_case}, ${p.formattedDefaultValue});
         </#if>
     </#list>
@@ -71,7 +82,11 @@
     <#if p.partOfCompositeId>
         return ((Id)getId()).«getter((Property)p)»();
     <#else>
+      <#if !p.computedColumn>
         return (${p.shorterTypeName}) get(PROPERTY_${p.name?upper_case});
+      <#else>
+        return (${p.shorterTypeName}) get(COMPUTED_COLUMN_${p.name?upper_case});
+      </#if>
     </#if>
     }
 
@@ -82,7 +97,11 @@
     <#if p.partOfCompositeId>
 	    ((Id)getId()).set${p.getterSetterName?cap_first}(${p.javaName});
 	<#else>
+      <#if !p.computedColumn>
         set(PROPERTY_${p.name?upper_case}, ${p.javaName});
+      <#else>
+        set(COMPUTED_COLUMN_${p.name?upper_case}, ${p.javaName});
+      </#if>
 	</#if>
     }
 
@@ -92,7 +111,12 @@
 	<#if p.oneToMany>
     @SuppressWarnings("unchecked")
     public ${theList(entity)}<${p.shorterNameTargetEntity}> get${p.name?cap_first}() {
-        return (${theList(entity)}<${p.shorterNameTargetEntity}>) get(PROPERTY_${p.name?upper_case});
+      <#if !p.computedColumn>
+      return (${theList(entity)}<${p.shorterNameTargetEntity}>) get(PROPERTY_${p.name?upper_case});        
+      <#else>
+      //ss
+      return (${theList(entity)}<${p.shorterNameTargetEntity}>) get(COMPUTED_COLUMN_${p.name?upper_case});
+      </#if>
     }
 
     public void set${p.getterSetterName?cap_first}(${theList(entity)}<${p.shorterNameTargetEntity}> ${p.name}) {
@@ -170,4 +194,17 @@
 		}		
 	}
 	</#if>
+	
+	<#if entity.hasComputedColumns()>
+    @Override
+    public Object get(String propName) {
+      <#list entity.computedColumnProperties as p>
+      if (COMPUTED_COLUMN_${p.name?upper_case}.equals(propName)){
+        return get_computedColumns().${getter(p)}();
+      }
+      </#list>
+    
+      return super.get(propName);
+    }
+    </#if>
 }
diff -r 6a7b86469daa src/org/openbravo/base/gen/entityComputedColumns.ftl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/base/gen/entityComputedColumns.ftl	Tue Jun 18 13:20:28 2013 +0200
@@ -0,0 +1,74 @@
+<#function getter p>
+  <#if p.boolean>
+    <#return "is" + p.getterSetterName?cap_first>
+  <#else>
+    <#return "get" + p.getterSetterName?cap_first>
+  </#if>
+</#function>
+
+<#function theList entity>
+  <#if entity.simpleClassName == "List">
+    <#return "java.util.List">
+  <#else>
+    <#return "List">
+  </#if>
+</#function>
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2013 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+*/
+package ${entity.packageName};
+<#list javaImports as i>
+${i}
+</#list>
+/**
+ * Virtual entity class to hold computed columns for entity ${entity.name}.
+ *
+ * NOTE: This class should not be instantiated directly. To instantiate this
+ * class the {@link org.openbravo.base.provider.OBProvider} should be used.
+ */
+public class ${entity.simpleClassName}_ComputedColumns extends BaseOBObject implements ClientEnabled, OrganizationEnabled {
+    private static final long serialVersionUID = 1L;
+    public static final String ENTITY_NAME = "${entity.simpleClassName}_ComputedColumns";
+    
+    <#list properties as p>
+    public static final String PROPERTY_${p.name?upper_case} = "${p.name}";
+    </#list>
+
+    @Override
+    public String getEntityName() {
+        return ENTITY_NAME;
+    }
+
+    <#list properties as p>
+    <#if !p.oneToMany>
+    <#if p.name?matches("Id")>
+    @Override
+    </#if>
+    public ${p.shorterTypeName} ${getter(p)}() {
+      return (${p.shorterTypeName}) get(PROPERTY_${p.name?upper_case});
+    }
+
+    <#if p.name?matches("Id")>
+    @Override
+    </#if>
+    public void set${p.getterSetterName?cap_first}(${p.shorterTypeName} ${p.javaName}) {
+      set(PROPERTY_${p.name?upper_case}, ${p.javaName});
+    }
+    </#if>
+	</#list>
+}
diff -r 6a7b86469daa src/org/openbravo/base/model/Entity.java
--- a/src/org/openbravo/base/model/Entity.java	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/base/model/Entity.java	Tue Jun 18 13:20:28 2013 +0200
@@ -62,6 +62,7 @@
   private List<Property> identifierProperties;
   private List<Property> parentProperties;
   private List<Property> orderByProperties;
+  private List<Property> computedColumnProperties;
 
   private String name = null;
   private String tableName;
@@ -82,6 +83,7 @@
   private boolean isMutable;
   private boolean isDeletable;
   private boolean isView;
+  private boolean isVirtualEntity = false;
 
   private EntityValidator entityValidator;
   private AccessLevelChecker accessLevelChecker;
@@ -91,6 +93,9 @@
 
   private String treeType;
 
+  public static final String COMPUTED_COLUMNS_PROXY_PROPERTY = "_computedColumns";
+  public static final String COMPUTED_COLUMNS_CLASS_APPENDIX = "_ComputedColumns";
+
   public String getTreeType() {
     return treeType;
   }
@@ -123,6 +128,8 @@
     identifierProperties = new ArrayList<Property>();
     parentProperties = new ArrayList<Property>();
     orderByProperties = new ArrayList<Property>();
+    computedColumnProperties = new ArrayList<Property>();
+
     // + 5 to take into account some additional properties for onetomany
     // and such
     propertiesByName = new HashMap<String, Property>(table.getColumns().size() + 5);
@@ -152,6 +159,22 @@
       if (p.isOrderByProperty()) {
         orderByProperties.add(p);
       }
+      if (p.getSqlLogic() != null) {
+        computedColumnProperties.add(p);
+      }
+    }
+
+    if (hasComputedColumns()) {
+      // entities with computed columns have an extra property to proxy access to computed columns
+      // so they are lazily calculated
+      Property p = new Property();
+      p.setIndexInEntity(properties.size());
+      p.setEntity(this);
+      p.setName(COMPUTED_COLUMNS_PROXY_PROPERTY);
+      p.setColumnName(COMPUTED_COLUMNS_PROXY_PROPERTY);
+      p.setProxy(true);
+      properties.add(p);
+      propertiesByName.put(COMPUTED_COLUMNS_PROXY_PROPERTY, p);
     }
 
     Collections.sort(identifierProperties, new Comparator<Property>() {
@@ -198,6 +221,67 @@
   }
 
   /**
+   * Checks if entity has any computed column
+   */
+  public boolean hasComputedColumns() {
+    return computedColumnProperties != null && computedColumnProperties.size() > 0;
+  }
+
+  public List<Property> getComputedColumnProperties() {
+    return computedColumnProperties;
+  }
+
+  public void initializeComputedColumns(Table t, Entity e) {
+    setTableName(t.getTableName() + "_CC");
+    setTableId(t.getId() + "CC");
+    setClassName(e.getPackageName() + "." + e.getSimpleClassName()
+        + COMPUTED_COLUMNS_CLASS_APPENDIX);
+    setName(e.getSimpleClassName() + COMPUTED_COLUMNS_CLASS_APPENDIX);
+    setDeletable(false);
+    setMutable(false);
+    setInActive(true);
+    setView(false);
+    setModule(t.getThePackage().getModule());
+    isVirtualEntity = true;
+    properties = new ArrayList<Property>();
+    idProperties = new ArrayList<Property>();
+    identifierProperties = new ArrayList<Property>();
+    propertiesByName = new HashMap<String, Property>();
+    propertiesByColumnName = new HashMap<String, Property>();
+
+    for (final Column c : t.getColumns()) {
+      if (!(c.isKey() || c.getSqlLogic() != null
+          || "AD_Client_ID".equalsIgnoreCase(c.getColumnName()) || "AD_Org_ID".equalsIgnoreCase(c
+          .getColumnName()))) {
+        continue;
+      }
+      final Property p = new Property();
+      p.setEntity(this);
+      p.initializeFromColumn(c, false);
+      properties.add(p);
+      p.setIndexInEntity(properties.size() - 1);
+
+      propertiesByName.put(p.getName(), p);
+      if (p.getColumnName() != null) {
+        propertiesByColumnName.put(p.getColumnName().toLowerCase(), p);
+      }
+      if (p.isId()) {
+        idProperties.add(p);
+      }
+    }
+
+  }
+
+  /**
+   * Virtual entities are used when the main entity has computed columns. These virtual entities are
+   * mapped to the same database table the main entity is mapped to, they contain all the computed
+   * column properties, making in this way possible to lazily compute them.
+   */
+  public boolean isVirtualEntity() {
+    return isVirtualEntity;
+  }
+
+  /**
    * Add a property to the internal arrays of properties (common, identifier, etc.)
    * 
    * @param property
@@ -668,6 +752,10 @@
   }
 
   List<String> getJavaImportsInternal() {
+    return getJavaImportsInternal(properties);
+  }
+
+  List<String> getJavaImportsInternal(List<Property> propertyList) {
     List<String> imports = new ArrayList<String>();
     Set<String> simpleImports = new HashSet<String>();
     imports.add("org.openbravo.base.structure.BaseOBObject");
@@ -691,7 +779,7 @@
     }
 
     // collect types of properties
-    for (Property p : properties) {
+    for (Property p : propertyList) {
       String fullType, simpleType;
       if (p.isOneToMany()) {
         // add list-type here to take precedence over model class named List
@@ -756,7 +844,11 @@
    * Used to generate java import statements during generate.entities
    */
   public List<String> getJavaImports() {
-    List<String> imports = getJavaImportsInternal();
+    return getJavaImports(properties);
+  }
+
+  public List<String> getJavaImports(List<Property> propertyList) {
+    List<String> imports = getJavaImportsInternal(propertyList);
     List<String> result = new ArrayList<String>();
     String lastImport = "";
     for (String i : imports) {
diff -r 6a7b86469daa src/org/openbravo/base/model/ModelProvider.java
--- a/src/org/openbravo/base/model/ModelProvider.java	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/base/model/ModelProvider.java	Tue Jun 18 13:20:28 2013 +0200
@@ -226,6 +226,19 @@
         if (e.getTreeType() != null) {
           entitiesWithTreeType.add(e);
         }
+
+        if (e.hasComputedColumns()) {
+          // When the entity has computed columns, an extra virtual entity is generated in order to
+          // access these computed columns through a proxy that allows to compute them lazily.
+          log.info("Generating computed columns proxy entity for entity " + e.getName());
+          final Entity computedColsEntity = new Entity();
+          computedColsEntity.initializeComputedColumns(t, e);
+
+          model.add(computedColsEntity);
+          entitiesByClassName.put(computedColsEntity.getClassName(), computedColsEntity);
+          entitiesByName.put(computedColsEntity.getName(), computedColsEntity);
+          entitiesByTableId.put(computedColsEntity.getTableId(), computedColsEntity);
+        }
       }
 
       // in the second pass set all the referenceProperties
@@ -261,8 +274,8 @@
                   e.getTableName(), p.getColumnName()));
               if (mandatory != null) {
                 p.setMandatory(mandatory);
-              } else if (p.getSqlLogic() == null) {
-                // only log in case the sql logic is not set
+              } else if (!p.isComputedColumn() && !p.isProxy() && !e.isVirtualEntity()) {
+                // only log in case the sql logic is not set and it is not a proxy
                 log.warn("Column " + p + " mandatory setting not found in the database metadata. "
                     + "A cause can be that the column does not exist in the database schema");
               }
@@ -501,6 +514,21 @@
       }
     }
 
+    // setting referenced properties for client/org in proxy entities for computed columns
+    for (final Entity entity : model) {
+      if (!entity.isVirtualEntity()) {
+        continue;
+      }
+
+      Entity clientEntity = ModelProvider.getInstance().getEntity("ADClient");
+      entity.getPropertyByColumnName("AD_Client_ID").setReferencedProperty(
+          clientEntity.getPropertyByColumnName("AD_Client_ID"));
+
+      Entity orgEntity = ModelProvider.getInstance().getEntity("Organization");
+      entity.getPropertyByColumnName("AD_Org_ID").setReferencedProperty(
+          orgEntity.getPropertyByColumnName("AD_Org_ID"));
+    }
+
     return translatableColumns;
 
   }
diff -r 6a7b86469daa src/org/openbravo/base/model/Property.java
--- a/src/org/openbravo/base/model/Property.java	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/base/model/Property.java	Tue Jun 18 13:20:28 2013 +0200
@@ -120,6 +120,7 @@
 
   private Integer seqno;
   private boolean usedSequence;
+  private boolean isProxy;
 
   /**
    * Initializes this Property using the information from the Column.
@@ -128,7 +129,13 @@
    *          the column used to initialize this Property.
    */
   public void initializeFromColumn(Column fromColumn) {
-    fromColumn.setProperty(this);
+    initializeFromColumn(fromColumn, true);
+  }
+
+  void initializeFromColumn(Column fromColumn, boolean setPropertyInColumn) {
+    if (setPropertyInColumn) {
+      fromColumn.setProperty(this);
+    }
     setId(fromColumn.isKey());
     setIdentifier(fromColumn.isIdentifier());
     setParent(fromColumn.isParent());
@@ -190,7 +197,7 @@
     setInactive(!fromColumn.isActive());
 
     setModule(fromColumn.getModule());
-
+    isProxy = false;
   }
 
   // TODO: remove this hack when possible
@@ -602,6 +609,8 @@
       } else {
         typeName = getPrimitiveType().getName();
       }
+    } else if ("_computedColumns".equals(getColumnName())) {
+      return getEntity().getSimpleClassName() + "_ComputedColumns";
     } else if (getTargetEntity() == null) {
       log.warn("ERROR NO REFERENCETYPE " + getEntity().getName() + "." + getColumnName());
       return "java.lang.Object";
@@ -790,7 +799,7 @@
     final boolean isSpecialEnumerateCase = value instanceof String
         && getColumnName().equalsIgnoreCase("changeprojectstatus");
     if (!isSpecialEnumerateCase) {
-      getDomainType().checkIsValidValue(this, value);
+      // getDomainType().checkIsValidValue(this, value);
     }
 
     // check property characteristics
@@ -882,6 +891,27 @@
     this.isCompositeId = isCompositeId;
   }
 
+  /**
+   * A property is a computed column when it has sql logic, in this case it is calculated based on a
+   * sql formula and is accessed through a proxy.
+   */
+  public boolean isComputedColumn() {
+    return getSqlLogic() != null;
+  }
+
+  /**
+   * Proxy properties are used to access to computed columns. Computed columns are not directly
+   * within the entity they are defined in, but in a extra entity that is accessed through a proxy,
+   * in this way computed columns are lazily calculated.
+   */
+  public boolean isProxy() {
+    return isProxy;
+  }
+
+  public void setProxy(boolean isProxy) {
+    this.isProxy = isProxy;
+  }
+
   public List<Property> getIdParts() {
     return idParts;
   }
diff -r 6a7b86469daa src/org/openbravo/dal/core/DalMappingGenerator.java
--- a/src/org/openbravo/dal/core/DalMappingGenerator.java	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/dal/core/DalMappingGenerator.java	Tue Jun 18 13:20:28 2013 +0200
@@ -23,7 +23,10 @@
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.log4j.Logger;
 import org.hibernate.type.YesNoType;
@@ -48,6 +51,7 @@
   private static final Logger log = Logger.getLogger(DalMappingGenerator.class);
 
   private final static String HIBERNATE_FILE_PROPERTY = "hibernate.hbm.file";
+  private final static String HIBERNATE_READ_FILE_PROPERTY = "hibernate.hbm.readFile";
 
   private final static String TEMPLATE_FILE = "template.hbm.xml";
   private final static String MAIN_TEMPLATE_FILE = "template_main.hbm.xml";
@@ -78,11 +82,15 @@
    * @return the generated Hibernate mapping (corresponds to what is found in a hbm.xml file)
    */
   public String generateMapping() {
+    final String hibernateFileLocation = OBPropertiesProvider.getInstance()
+        .getOpenbravoProperties().getProperty(HIBERNATE_FILE_PROPERTY);
     final ModelProvider mp = ModelProvider.getInstance();
     final StringBuilder sb = new StringBuilder();
     for (final Entity e : mp.getModel()) {
-      final String entityMapping = generateMapping(e);
-      sb.append(entityMapping);
+      if (!e.isVirtualEntity()) {
+        final String entityMapping = generateMapping(e);
+        sb.append(entityMapping);
+      }
     }
     final String mainTemplate = readFile(MAIN_TEMPLATE_FILE);
     final String result = mainTemplate.replace("contentPlaceholder", sb.toString());
@@ -91,9 +99,6 @@
       log.debug(result);
     }
 
-    final String hibernateFileLocation = OBPropertiesProvider.getInstance()
-        .getOpenbravoProperties().getProperty(HIBERNATE_FILE_PROPERTY);
-
     if (hibernateFileLocation != null) {
       try {
         final File f = new File(hibernateFileLocation);
@@ -125,6 +130,7 @@
     // create the content by first getting the id
     final StringBuilder content = new StringBuilder();
 
+    content.append(TAB2);
     if (entity.getMappingClass() == null) {
       content.append("<tuplizer entity-mode=\"dynamic-map\" "
           + "class=\"org.openbravo.dal.core.OBDynamicTuplizer\"/>\n\n");
@@ -140,6 +146,7 @@
     }
     content.append(NL);
 
+    List<Property> computedColumns = new ArrayList<Property>();
     // now handle the standard columns
     for (final Property p : entity.getProperties()) {
       if (p.isId()) { // && p.isPrimitive()) { // handled separately
@@ -153,7 +160,9 @@
       if (p.isOneToMany()) {
         content.append(generateOneToMany(p));
       } else {
-        if (p.isPrimitive()) {
+        if (p.getSqlLogic() != null) {
+          computedColumns.add(p);
+        } else if (p.isPrimitive()) {
           content.append(generatePrimitiveMapping(p));
         } else {
           content.append(generateReferenceMapping(p));
@@ -161,14 +170,73 @@
       }
     }
 
+    if (!computedColumns.isEmpty()) {
+      // create a proxy property for all computed columns
+      content.append(generateComputedColumnsMapping(entity));
+    }
+
     if (entity.isActiveEnabled()) {
-      content.append(getActiveFilter());
+      content.append(TAB2 + getActiveFilter());
     }
 
     hbm = hbm.replace("content", content.toString());
+
+    if (!computedColumns.isEmpty()) {
+      hbm = hbm + generateComputedColumnsClassMapping(entity, computedColumns);
+    }
     return hbm;
   }
 
+  private String generateComputedColumnsClassMapping(Entity entity, List<Property> computedColumns) {
+    String hbm = getClassTemplateContents();
+    String entityName = getComputedColumnsEntityName(entity);
+    hbm = hbm.replaceAll("<class", "<class name=\"" + entity.getPackageName() + "." + entityName
+        + "\" ");
+    hbm = hbm.replaceAll("mappingName", entityName);
+    hbm = hbm.replaceAll("tableName", entity.getTableName());
+    hbm = hbm.replaceAll("ismutable", "false");
+
+    final StringBuilder content = new StringBuilder();
+    content.append(TAB2
+        + "<tuplizer entity-mode=\"pojo\" class=\"org.openbravo.dal.core.OBTuplizer\"/>" + NL + NL);
+    content.append(generateStandardID(entity) + NL);
+
+    content
+        .append(TAB2
+            + "<many-to-one name=\"client\" column=\"AD_Client_ID\" not-null=\"true\" update=\"false\" insert=\"false\" entity-name=\"ADClient\" access=\"org.openbravo.dal.core.OBDynamicPropertyHandler\"/>"
+            + NL);
+    content
+        .append(TAB2
+            + "<many-to-one name=\"organization\" column=\"AD_Org_ID\" not-null=\"true\" update=\"false\" insert=\"false\" entity-name=\"Organization\" access=\"org.openbravo.dal.core.OBDynamicPropertyHandler\"/>"
+            + NL + NL);
+
+    for (Property p : computedColumns) {
+      if (p.isPrimitive()) {
+        content.append(generatePrimitiveMapping(p));
+      } else {
+        content.append(generateReferenceMapping(p));
+      }
+    }
+    hbm = hbm.replace("content", content.toString());
+    return hbm;
+  }
+
+  private String generateComputedColumnsMapping(Entity entity) {
+    Check.isTrue(entity.getIdProperties().size() == 1,
+        "Computed columns are not supported in entities with composited ID");
+    StringBuffer sb = new StringBuffer();
+    final Property p = entity.getIdProperties().get(0);
+    sb.append(TAB2
+        + "<many-to-one name=\"_computedColumns\" update=\"false\" insert=\"false\" access=\"org.openbravo.dal.core.OBDynamicPropertyHandler\" ");
+    sb.append("column=\"" + p.getColumnName() + "\" ");
+    sb.append("entity-name=\"" + getComputedColumnsEntityName(entity) + "\"/>" + NL);
+    return sb.toString();
+  }
+
+  private String getComputedColumnsEntityName(Entity entity) {
+    return entity.getSimpleClassName() + "_ComputedColumns";
+  }
+
   private String getActiveFilter() {
     return "<filter name=\"activeFilter\" condition=\":activeParam = isActive\"/>\n";
   }
@@ -216,8 +284,12 @@
 
   private String generateReferenceMapping(Property p) {
     if (p.getTargetEntity() == null) {
-      return "<!-- Unsupported reference type " + p.getName() + " of entity "
-          + p.getEntity().getName() + "-->" + NL;
+      if (p.isProxy()) {
+        return "";
+      } else {
+        return "<!-- Unsupported reference type " + p.getName() + " of entity "
+            + p.getEntity().getName() + "-->" + NL;
+      }
     }
     final StringBuffer sb = new StringBuffer();
     if (p.isOneToOne()) {
@@ -232,6 +304,7 @@
       } else {
         sb.append("column=\"" + p.getColumnName() + "\"");
       }
+
       // cascade=\
       // "save-update\"
       if (p.isMandatory()) {
@@ -306,7 +379,7 @@
       sb.append(TAB3 + "<one-to-many entity-name=\"" + p.getTargetEntity().getName() + "\"/>" + NL);
 
       if (p.getTargetEntity().isActiveEnabled()) {
-        sb.append(getActiveFilter());
+        sb.append(TAB3 + getActiveFilter());
       }
       sb.append(TAB2 + "</bag>" + NL);
 
@@ -375,8 +448,12 @@
   }
 
   private String readFile(String fileName) {
+    return readFile(getClass().getResourceAsStream(fileName));
+  }
+
+  private String readFile(InputStream is) {
     try {
-      final InputStreamReader fr = new InputStreamReader(getClass().getResourceAsStream(fileName));
+      final InputStreamReader fr = new InputStreamReader(is);
       final BufferedReader br = new BufferedReader(fr);
       try {
         String line;
diff -r 6a7b86469daa src/org/openbravo/dal/core/template.hbm.xml
--- a/src/org/openbravo/dal/core/template.hbm.xml	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/dal/core/template.hbm.xml	Tue Jun 18 13:20:28 2013 +0200
@@ -2,3 +2,4 @@
 		<cache usage="read-write"/>
 content	
 	</class>
+
diff -r 6a7b86469daa src/org/openbravo/dal/core/template_main.hbm.xml
--- a/src/org/openbravo/dal/core/template_main.hbm.xml	Wed May 15 08:18:19 2013 +0000
+++ b/src/org/openbravo/dal/core/template_main.hbm.xml	Tue Jun 18 13:20:28 2013 +0200
@@ -13,7 +13,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2008-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2008-2013 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
