Index: trunk/fmgVen/src/com/fmguler/ven/QueryGenerator.java
===================================================================
--- trunk/fmgVen/src/com/fmguler/ven/QueryGenerator.java	(revision 25)
+++ trunk/fmgVen/src/com/fmguler/ven/QueryGenerator.java	(revision 26)
@@ -18,6 +18,11 @@
 package com.fmguler.ven;
 
+import com.fmguler.ven.util.Convert;
+import java.beans.PropertyDescriptor;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
 
 /**
@@ -27,7 +32,15 @@
 public class QueryGenerator {
     private Set domainPackages;
+    private Set dbClasses;
 
     public QueryGenerator() {
         domainPackages = new HashSet();
+        dbClasses = new HashSet();
+        //the predefined database classes;
+        this.dbClasses.add(Integer.class);
+        this.dbClasses.add(String.class);
+        this.dbClasses.add(Date.class);
+        this.dbClasses.add(Double.class);
+        this.dbClasses.add(Boolean.class);
     }
 
@@ -40,9 +53,77 @@
     }
 
-    public String generateUpdateQuery() {
-        return null;
+    public String generateInsertQuery(Object object) throws VenException {
+        BeanWrapper wr = new BeanWrapperImpl(object);
+        String objectName = Convert.toSimpleName(object.getClass().getName());
+        String tableName = Convert.toDB(objectName);
+        PropertyDescriptor[] pdArr = wr.getPropertyDescriptors();
+
+        //generate insert query
+        StringBuffer query = new StringBuffer("insert into " + tableName + "(");
+        StringBuffer values = new StringBuffer(" values(");
+        for (int i = 0; i < pdArr.length; i++) {
+            Class fieldClass = pdArr[i].getPropertyType(); //field class
+            String columnName = Convert.toDB(pdArr[i].getName()); //column name
+            String fieldName = pdArr[i].getName(); //field name
+            //if (fieldName.equals("id")) continue; //remove if it does not break the sequence
+            if (dbClasses.contains(fieldClass)) { //direct database field (Integer,String,Date, etc)
+                query.append(columnName);
+                query.append(",");
+                values.append(":").append(fieldName);
+                values.append(",");
+            }
+            if (fieldClass.getPackage() != null && domainPackages.contains(fieldClass.getPackage().getName())) { //object
+                query.append(Convert.toDB(fieldName)).append("_id");
+                query.append(",");
+                values.append(":").append(fieldName).append(".id");
+                values.append(",");
+            }
+        }
+        query.deleteCharAt(query.length() - 1);
+        query.append(")");
+        values.deleteCharAt(values.length() - 1);
+        values.append(");");
+        query.append(values);
+
+        return query.toString();
     }
 
-    //SETTERS-------------------------------------------------------------------
+    /**
+     * Generates insert/update query
+     * @return the insert update SQL query
+     */
+    public String generateUpdateQuery(Object object) throws VenException {
+        BeanWrapper wr = new BeanWrapperImpl(object);
+        String objectName = Convert.toSimpleName(object.getClass().getName());
+        String tableName = Convert.toDB(objectName);
+        PropertyDescriptor[] pdArr = wr.getPropertyDescriptors();
+
+        StringBuffer query = new StringBuffer("update " + tableName + " set ");
+        for (int i = 0; i < pdArr.length; i++) {
+            Class fieldClass = pdArr[i].getPropertyType(); //field class
+            String columnName = Convert.toDB(pdArr[i].getName()); //column name
+            String fieldName = pdArr[i].getName(); //field name
+            if (dbClasses.contains(fieldClass)) { //direct database field (Integer,String,Date, etc)
+                query.append(columnName).append("=:").append(fieldName);
+                query.append(",");
+            }
+            if (fieldClass.getPackage() != null && domainPackages.contains(fieldClass.getPackage().getName())) { //object
+                query.append(columnName).append("_id=:").append(fieldName).append(".id");
+                query.append(",");
+            }
+        }
+        query.deleteCharAt(query.length() - 1);
+        query.append(" where id = :id ;"); //TODO: remove the last comma
+        return query.toString();
+    }
+
+    public String generateSequenceQuery(Object object) throws VenException {
+        String objectName = Convert.toSimpleName(object.getClass().getName());
+        String tableName = Convert.toDB(objectName);
+        return "select nextval('" + tableName + "_id_seq');";
+    }
+
+    //--------------------------------------------------------------------------
+    //SETTERS
     public void addDomainPackage(String domainPackage) {
         domainPackages.add(domainPackage);
Index: trunk/fmgVen/src/com/fmguler/ven/Ven.java
===================================================================
--- trunk/fmgVen/src/com/fmguler/ven/Ven.java	(revision 25)
+++ trunk/fmgVen/src/com/fmguler/ven/Ven.java	(revision 26)
@@ -18,7 +18,12 @@
 package com.fmguler.ven;
 
+import java.util.HashMap;
 import java.util.List;
 import javax.sql.DataSource;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 
 /**
@@ -44,15 +49,56 @@
     }
 
-    public Object get(int no, Class objectClass) {
+    public Object get(int id, Class objectClass) {
         return null;
     }
 
+    /**
+     * Save the object. If it has a "id" property it will be updated.
+     * It will be inserted otherwise.
+     * <p>
+     * The object will be saved to a table with the same name as the object,
+     * The fields of object will be mapped to the table fields.
+     * 
+     * @param object the object to be saved
+     */
     public void save(Object object) {
+        String query = null;
+
+        if (isObjectNew(object)) {
+            //if this is a new object assign a new id first
+            generateId(object);
+            query = generator.generateInsertQuery(object);
+        } else {
+            query = generator.generateUpdateQuery(object);
+        }
+
+        //execute the insert/update query
+        SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(object);
+        template.update(query, parameterSource);
     }
 
-    public void delete(int no, Class objectClass) {
+    public void delete(int id, Class objectClass) {
     }
 
-    //SETTERS-------------------------------------------------------------------
+    //--------------------------------------------------------------------------
+    //PRIVATE METHODS
+    //return true if the object id is zero or null false otherwise
+    private boolean isObjectNew(Object object) throws VenException {
+        BeanWrapper beanWrapper = new BeanWrapperImpl(object);
+        Object objectId = beanWrapper.getPropertyValue("id"); 
+        if (objectId == null) return true;
+        if (!(objectId instanceof Integer)) throw new VenException(VenException.EC_GENERATOR_OBJECT_ID_TYPE_INVALID);
+        return ((Integer)objectId).intValue() == 0;
+    }
+
+    //set new object id
+    private void generateId(Object object) {
+        Integer newObjectId = new Integer(template.queryForInt(generator.generateSequenceQuery(object), new HashMap()));
+        BeanWrapper beanWrapper = new BeanWrapperImpl(object);
+        beanWrapper.setPropertyValue("id", newObjectId);
+    }
+
+    //--------------------------------------------------------------------------
+    //SETTERS
     public void setDataSource(DataSource dataSource) {
         if (dataSource == null) throw new RuntimeException("fmgVen - DataSource cannot be null");
Index: trunk/fmgVen/src/com/fmguler/ven/VenException.java
===================================================================
--- trunk/fmgVen/src/com/fmguler/ven/VenException.java	(revision 26)
+++ trunk/fmgVen/src/com/fmguler/ven/VenException.java	(revision 26)
@@ -0,0 +1,74 @@
+/*
+ *  fmgVen - A Convention over Configuration Java ORM Tool
+ *  Copyright 2010 Fatih Mehmet Güler
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+package com.fmguler.ven;
+
+/**
+ * All kinds of exceptions in Ven operations.
+ * @author Fatih Mehmet Güler
+ */
+public class VenException extends RuntimeException {
+    private String errorCode;
+    private String errorParam;
+    //Error codes
+    //"Invalid object, \"id\" property must be of integer type"
+    public static final String EC_GENERATOR_OBJECT_ID_TYPE_INVALID = "ec-generator-object-id-type-invalid";
+
+    /**
+     * Init VenException with an error code
+     * @param errorCode the error code
+     */
+    public VenException(String errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    /**
+     * Init VenException with an error code and an error parameter
+     * @param errorCode the error code
+     * @param errorParam the error param
+     */
+    public VenException(String errorCode, String errorParam) {
+        this.errorCode = errorCode;
+        this.errorParam = errorParam;
+    }
+
+    /**
+     * Init VenException with an error code, error parameter and the cause of the exception
+     * @param errorCode the error code
+     * @param errorParam the error parameter
+     * @param cause the cause of the exception
+     */
+    public VenException(String errorCode, String errorParam, Throwable cause) {
+        super(cause);
+        this.errorCode = errorCode;
+        this.errorParam = errorParam;
+    }
+
+    /**
+     * @return the error code of the exception
+     */
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    /**
+     * @return the error parameter of the exception, which can contain details about the error
+     */
+    public String getErrorParam() {
+        return errorParam;
+    }
+}
Index: trunk/fmgVen/src/com/fmguler/ven/util/Convert.java
===================================================================
--- trunk/fmgVen/src/com/fmguler/ven/util/Convert.java	(revision 26)
+++ trunk/fmgVen/src/com/fmguler/ven/util/Convert.java	(revision 26)
@@ -0,0 +1,61 @@
+/*
+ *  fmgVen - A Convention over Configuration Java ORM Tool
+ *  Copyright 2010 Fatih Mehmet Güler
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+package com.fmguler.ven.util;
+
+import java.util.Locale;
+
+/**
+ * Utility class for conversions from database naming convention to java, and vice versa
+ * @author Fatih Mehmet Güler
+ */
+public class Convert {
+    /**
+     * Convert from java camelCase case to database naming convention
+     * <p>
+     * For example, if the name of the given name is SomeDomainObject
+     * it will be converted to some_domain_object
+     *
+     * @param camelCase the camelCase case name
+     * @return database style name
+     */
+    public static String toDB(String camelCase) {
+        if (camelCase.equals("")) return "";
+        StringBuffer result = new StringBuffer();
+        result.append(camelCase.substring(0, 1).toLowerCase(Locale.ENGLISH));
+        for (int i = 1; i < camelCase.length(); i++) {
+            String sCamel = camelCase.substring(i, i + 1);
+            String sLower = sCamel.toLowerCase(Locale.ENGLISH);
+            if (!sCamel.equals(sLower)) {
+                result.append("_").append(sLower);
+            } else result.append(sCamel);
+        }
+        return result.toString();
+    }
+
+    /**
+     * Convert the full package name to simple name.
+     * For Java 1.4 compatibility of Class.getSimpleName()
+     * @param fullName Class.getName()
+     * @return the part after the last .
+     */
+    public static String toSimpleName(String fullName) {
+        int i = fullName.lastIndexOf(".");
+        if (i < 0) return fullName;
+        return fullName.substring(i + 1);
+    }
+}
