|
Project Information
Featured
Downloads
Links
|
Another ORM for SimpleDB?This is a simple java-based object-relational mapping (ORM) framework, targeting people who used to develop against Hibernate ORM. Knowledge of Hibernate is not required, but will definitely help. What is wrong with simplejpa? Nothing wrong, it is a great project and please check it out. I am not a fan of JPA and my goal was to make this as light as possible with as less dependencies as possible. This framework is not perfect. Frankly, I would prefer to have SimpleDB jdbc driver with SimpleDB Hibernate Dialect, but too lazy to do that. Maybe someone will act on this idea. Some Features:
Getting Started:Note: this projects depends on netflexity-amazonws-simpledb project, which provides client API to Amazon SimpleDB. I suggest to start Amazon SimpleDB modeling with MySQL or any other relational database that you are the most familiar and productive with. Create the model. Make sure to use VARCHAR for primary and foreign keys. Make sure that you have no composite primary keys; this is the recommended approach for normalization anyway. Reverse-engineer your schema with Hibernate Tools. Make minor adjustments to support Domains and Logical names if necessary. Create DAO layer with SimpleDB ORM and have fun doing it! Usage Example// Find all party objects.
SimpleDBSession simpledbSession = (SimpleDBSession) context.getBean("simpledbSessionFactory");
Set<Party> parties = simpledbSession.findAll(Party.class, "companyName");
for (Party nfxParty : parties) {
System.out.println(RecordUtil.toString(simpledbSession.getMetadata(Party.class), nfxParty));
}
// Add User with many-to-one account and 2 roles, setup as many-to-many. Note that
// many-to-many is mapped to Item Attributes with multiple values, which is very convenient :)
Role role = new Role();
role.setName("Administrator 3");
simpledbSession.save(role);
Role role2 = new Role();
role2.setName("Developer 3");
simpledbSession.save(role2);
Account account = new Account();
account.setId("3ca5b4b8-5d0b-4ed0-8908-bd6f046a3581");
User user = new User();
user.setUsername("maxim");
user.setPassword("password1");
user.setStatus("A");
user.setChangeBy("Somebody");
user.setChangeDate(System.currentTimeMillis());
user.setNfxAccount(account);
user.getNfxRoles().add(role);
user.getNfxRoles().add(role2);
simpledbSession.save(user);
// Test In clause.
Predicate<Role> predicate = Predicates.getInPredicate(Role.class, simpledbSession.getFactory().getMapping(), "name", new String[]{"Administrator 3", "Developer 3"});
List<Role> roles = simpledbSession.select(predicate, new String[]{});
for (Role role : roles) {
System.out.println(RecordUtil.toString(simpledbSession.getMetadata(Role.class), role));
}
// Load all lazy dependencies of user objects.
User user = simpledbSession.find(User.class, "e78cb0c6-0de9-4df5-9f07-1391f112ab5c");
simpledbSession.populate(user);
// Test Count.
int parties = simpledbSession.count(new TypeFilter<Party>(Party.class, simpledbSession.getFactory().getMapping()));
System.out.println(parties + " parties found!");
// Test DaoSupport to make easier writing Daos.
RoleDaoImpl roleDao = (RoleDaoImpl)context.getBean("roleDao");
Role admin3 = roleDao.find("Administrator 3");
Spring ConfigurationThis is an example of SimpleDB ORM setup with Ehcache as a 2nd level cache. There is a reference to simpledbDataSource, which is a SimpleDB client for Amazon SimpleDB that you can find here. mappingResource property points to sample.xml, which is a hibernate-like configuration file, which is 99% like .hbm.xml files, but with a different root element. <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml"/> </bean> <bean id="ehcacheFactory" class="com.netflexitysolutions.amazonws.sdb.orm.cache.EhcacheLevel2CacheFactory"> <property name="cacheManager" ref="cacheManager"/> </bean> <bean id="simpledbSessionFactory" class="com.netflexitysolutions.amazonws.sdb.orm.SimpleDBSessionFactoryBean"> <property name="dataSource" ref="simpledbDataSource"/> <property name="cacheFactory" ref="ehcacheFactory"/> <property name="mappingResource" value="classpath:sample.xml"/> <property name="mappingRulesResource" value="classpath:com/netflexitysolutions/amazonws/sdb/orm/metadata/simpledb-mapping-rules.xml"/> </bean> <!-- Dao --> <bean id="roleDao" class="com.netflexitysolutions.commons.amazonws.sdb.dao.RoleDaoImpl"> <constructor-arg ref="simpledbSessionFactory"/> </bean> Sample Ehcache Configuration<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<cacheManagerEventListenerFactory class="" properties=""/>
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic,
multicastGroupAddress=230.0.0.1,
multicastGroupPort=4446, timeToLive=1"/><!-- propertySeparator="," -->
<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/><!-- diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" -->
</ehcache>Sample Hibernate-like configurationCouple things to note:
<?xml version="1.0" encoding="utf-8"?>
<simpledb-mapping>
<class name="com.netflexitysolutions.amazonws.sample.domain.Party" table="QflexCE" discriminator-value="Party">
<id name="id" type="java.lang.String">
<column name="id" />
<generator class="identity" />
</id>
<property name="companyName" type="java.lang.String">
<column name="company_name" length="128" not-null="true">
<comment>Company name.</comment>
</column>
</property>
<property name="addressLine1" type="java.lang.String">
<column name="address_line1" length="128">
<comment>Address line 1.</comment>
</column>
</property>
<property name="addressLine2" type="java.lang.String">
<column name="address_line2" length="128">
<comment>Address line 2.</comment>
</column>
</property>
<property name="city" type="java.lang.String">
<column name="city" length="48">
<comment>City name.</comment>
</column>
</property>
<property name="stateProvince" type="java.lang.String">
<column name="state_province" length="48">
<comment>State or province.</comment>
</column>
</property>
<property name="postalCode" type="java.lang.String">
<column name="postal_code" length="16">
<comment>Postal code.</comment>
</column>
</property>
<property name="countryCode" type="java.lang.String">
<column name="country_code" length="16">
<comment>Country code.</comment>
</column>
</property>
<property name="billingContactName" type="java.lang.String">
<column name="billing_contact_name" length="48">
<comment>Contact name.</comment>
</column>
</property>
<property name="billingContactPhone" type="java.lang.String">
<column name="billing_contact_phone" length="16">
<comment>Contact phone.</comment>
</column>
</property>
<property name="billingContactEmail" type="java.lang.String">
<column name="billing_contact_email" length="64">
<comment>Contact email.</comment>
</column>
</property>
<property name="changeBy" type="java.lang.String">
<column name="change_by" length="32" />
</property>
<property name="changeDate" type="java.lang.Long">
<column name="change_date" />
</property>
<set name="nfxAccounts" inverse="true" lazy="false">
<key>
<column name="party_id" not-null="true">
<comment>Company.</comment>
</column>
</key>
<one-to-many class="com.netflexitysolutions.amazonws.sample.domain.Account" lazy="false"/>
</set>
</class>
<class name="com.netflexitysolutions.amazonws.sample.domain.Account" table="QflexCE" discriminator-value="Account">
<id name="id" type="java.lang.String">
<column name="id" />
<generator class="identity" />
</id>
<many-to-one name="nfxParty" class="com.netflexitysolutions.amazonws.sample.domain.Party" fetch="select">
<column name="party_id" not-null="true">
<comment>Company.</comment>
</column>
</many-to-one>
<property name="uuid" type="java.lang.String">
<column name="uuid" length="16" not-null="true">
<comment>Account auto-generated string id.</comment>
</column>
</property>
<property name="licenseContent" type="java.lang.String">
<column name="license_content" not-null="true">
<comment>License content in XML.</comment>
</column>
</property>
<property name="effectiveDate" type="java.lang.Long">
<column name="effective_date" not-null="true">
<comment>Date membership becomes valid.</comment>
</column>
</property>
<property name="expirationDate" type="java.lang.Long">
<column name="expiration_date" not-null="true">
<comment>Date membership expires.</comment>
</column>
</property>
<property name="creationDate" type="java.util.Date">
<column name="creation_date" not-null="true">
<comment>Date account established.</comment>
</column>
</property>
<property name="changeBy" type="java.lang.String">
<column name="change_by" length="32" />
</property>
<property name="changeDate" type="java.lang.Long">
<column name="change_date" />
</property>
<property name="status" type="java.lang.String">
<column name="status" length="1" not-null="true">
<comment>A - ACTIVE, I - INACTIVE</comment>
</column>
</property>
<set name="nfxUsers" inverse="true">
<key>
<column name="account_id" not-null="true" />
</key>
<one-to-many class="com.netflexitysolutions.amazonws.sample.domain.User" />
</set>
</class>
<class name="com.netflexitysolutions.amazonws.sample.domain.User" table="QflexCE" discriminator-value="User">
<id name="id" type="java.lang.String">
<column name="id" />
<generator class="identity" />
</id>
<many-to-one name="nfxAccount" class="com.netflexitysolutions.amazonws.sample.domain.Account" fetch="select">
<column name="account_id" not-null="true" />
</many-to-one>
<property name="username" type="java.lang.String">
<column name="username" length="32" not-null="true">
<comment>Username</comment>
</column>
</property>
<property name="password" type="java.lang.String">
<column name="password" length="32" not-null="true">
<comment>Password</comment>
</column>
</property>
<property name="changeDate" type="java.lang.Long">
<column name="change_date" />
</property>
<property name="changeBy" type="java.lang.String">
<column name="change_by" length="32" />
</property>
<property name="status" type="java.lang.String">
<column name="status" length="1" not-null="true" />
</property>
<!--set name="nfxUserRoles" inverse="true">
<key>
<column name="user_id" not-null="true" />
</key>
<one-to-many class="com.netflexitysolutions.amazonws.sample.domain.Role" />
</set-->
<bag name="nfxRoles" lazy="false">
<key>
<column name="role_id" not-null="true" />
</key>
<many-to-many column="name" class="com.netflexitysolutions.amazonws.sample.domain.Role"/>
</bag>
</class>
<class name="com.netflexitysolutions.amazonws.sample.domain.Role" table="Security" discriminator-value="Role">
<id name="name" type="java.lang.String">
<column name="name" />
<generator class="identity" />
</id>
</class>
</simpledb-mapping>
|