Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/sales.git
pom.xml
<version>5.1.0.Final</version>
</dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-jpamodelgen</artifactId>
+ <version>5.1.0.Final</version>
+ </dependency>
</dependencies>
<properties>
src/main/java/com/whitemagicsoftware/sales/BusinessEntity.java
@MappedSuperclass
public class BusinessEntity implements Serializable {
-
+
@Id
private int id;
/**
* Full name, first name, last name, etc.
*/
@Transient
private EntityName entityName;
-
+
public BusinessEntity() {
}
-
+
protected void setId( int id ) {
this.id = id;
return this.id;
}
-
+
protected String getName() {
return getEntityName().getName();
}
-
+
protected void setName( String name ) {
setEntityName( name );
return this.entityName;
}
-
+
protected String nullSafe( String s ) {
return s == null ? "" : s;
*/
protected static abstract class Builder<T extends BusinessEntity, B extends Builder<T, B>> {
-
+
private final T object;
private final B builder;
-
+
protected abstract T createObject();
-
+
protected abstract B getBuilder();
-
+
@SuppressWarnings( "OverridableMethodCallInConstructor" )
public Builder() {
this.object = createObject();
this.builder = getBuilder();
}
-
+
+ public B withId( int id ) {
+ getObject().setId( id );
+ return getBuilder();
+ }
+
public B withEntityName( EntityName entityName ) {
getObject().setEntityName( entityName );
return getBuilder();
}
-
+
public B withName( String name ) {
withEntityName( new EntityName( name ) );
return getBuilder();
}
-
+
public T build() {
return getObject();
}
-
+
protected T getObject() {
return this.object;
src/main/java/com/whitemagicsoftware/sales/Main.java
for( Subscription subscription : getSubscriptions( subscriber, vendor ) ) {
Scraper scraper = getScraper( vendor );
-
+
Product product = subscription.getProduct();
src/main/java/com/whitemagicsoftware/sales/Price.java
public final class Price extends BusinessEntity {
+ private static final long serialVersionUID = 0L;
+
/**
* How much does a product cost?
src/main/java/com/whitemagicsoftware/sales/Product.java
*/
@Entity
-@Table( name = "product" )
+@Table( name = "product_vw" )
public class Product extends BusinessEntity {
+ private static final long serialVersionUID = 0L;
+
/**
* Setting this value will indirectly set the entity name.
*/
- @Column( name = "product_name" )
+ @Column( name = "product_name", updatable = false, insertable = false, nullable = false )
private String name;
/**
* Path to the product page for products that have their own web page.
*/
- @Column( name = "product_path" )
+ @Column( name = "product_path", updatable = false, insertable = false, nullable = true )
private String urlPath;
src/main/java/com/whitemagicsoftware/sales/Subscription.java
package com.whitemagicsoftware.sales;
+import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
public class Subscription extends BusinessEntity {
- @OneToOne
+ private static final long serialVersionUID = 0L;
+
+ @OneToOne()
+ @JoinColumn( name = "product_id", referencedColumnName = "id" )
private Product product;
-
+
+ @Column( name = "subscriber_id", insertable = false, updatable = false, nullable = false )
+ private int subscriberId;
+
+ @Column( name = "vendor_id", insertable = false, updatable = false, nullable = false )
+ private int vendorId;
+
+ @Column( name = "product_id", insertable = false, updatable = false, nullable = false )
+ private int productId;
+
public Subscription() {
}
-
+
+ public void setProduct( Product product ) {
+ this.product = product;
+ }
+
protected Product getProduct() {
return this.product;
+ }
+
+ protected int getSubscriberId() {
+ return this.subscriberId;
+ }
+
+ protected void setSubscriberId( int subscriberId ) {
+ this.subscriberId = subscriberId;
+ }
+
+ protected int getVendorId() {
+ return this.vendorId;
+ }
+
+ protected void setVendorId( int vendorId ) {
+ this.vendorId = vendorId;
+ }
+
+ protected int getProductId() {
+ return this.productId;
+ }
+
+ protected void setProductId( int productId ) {
+ this.productId = productId;
}
}
src/main/java/com/whitemagicsoftware/sales/Vendor.java
* The script to run for this Vendor.
*/
- @Column( name = "script" )
+ @Column( name = "script", updatable = false, insertable = false )
private String scriptName;
src/main/java/com/whitemagicsoftware/sales/service/SubscriptionService.java
/**
- * Returns a list of subscriptions for a given subscriber and vendor pairing.
+ * Returns a list of products for a given subscriber and vendor pairing.
*
* @param subscriber The subscriber that has subscriptions to sale notifications.
src/main/java/com/whitemagicsoftware/sales/service/impl/ServiceImpl.java
import com.whitemagicsoftware.sales.service.Service;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
- * Creates a new list of items.
+ * Returns the list of all entries in the database for the given class type.
*
- * @return An empty, non-null ArrayList.
+ * @param clazz The class that represents an entity that has rows in a table
+ * within a database.
+ *
+ * @return The instances of the class populated with data from the database.
*/
- protected List<T> createList() {
- return new ArrayList<>();
- }
+ protected List<T> getResultList( Class<T> clazz ) {
+ CriteriaQuery<T> cq = createQuery( clazz );
+ Root<T> root = cq.from( clazz );
+ CriteriaQuery<T> all = cq.select( root );
- protected CriteriaBuilder getCriteriaBuilder() {
- return getEntityManager().getCriteriaBuilder();
+ List<T> result = createQuery( all ).getResultList();
+
+ closeEntityManager();
+
+ return result;
}
- private synchronized EntityManager getEntityManager() {
+ protected synchronized EntityManager getEntityManager() {
if( this.entityManager == null ) {
this.entityManager = getEntityManagerFactory().createEntityManager();
}
-
+
return this.entityManager;
+ }
+
+ private void closeEntityManager() {
+ getEntityManager().close();
}
return Persistence.createEntityManagerFactory( getPersistenceUnitName(),
getPersistenceProperties() );
+ }
+
+ protected CriteriaBuilder getCriteriaBuilder() {
+ return getEntityManager().getCriteriaBuilder();
+ }
+
+ protected CriteriaQuery<T> createQuery( Class<T> clazz ) {
+ return getCriteriaBuilder().createQuery( clazz );
+ }
+
+ protected TypedQuery<T> createQuery( String sql, Class<T> clazz ) {
+ return getEntityManager().createQuery( sql, clazz );
+ }
+
+ protected TypedQuery<T> createQuery( CriteriaQuery<T> cq ) {
+ return getEntityManager().createQuery( cq );
}
private String getPersistencePassword() {
return System.getProperty( PERSISTENCE_PASSWORD_PROPERTY );
+ }
+
+ private String getPersistenceUnitName() {
+ return "SALES";
}
private String nullSafe( String s ) {
return s == null ? "" : s;
- }
-
- private String getPersistenceUnitName() {
- return "SALES";
- }
-
- protected CriteriaQuery<T> createQuery( Class<T> clazz ) {
- return getCriteriaBuilder().createQuery( clazz );
- }
-
- protected TypedQuery<T> createQuery( String sql, Class<T> clazz ) {
- return getEntityManager().createQuery( sql, clazz );
- }
-
- protected TypedQuery<T> createQuery( CriteriaQuery<T> cq ) {
- return getEntityManager().createQuery( cq );
- }
-
- /**
- * Returns the list of all entries in the database for the given class type.
- *
- * @param clazz The class that represents an entity that has rows in a table
- * within a database.
- *
- * @return The instances of the class populated with data from the database.
- */
- protected List<T> getResultList( Class<T> clazz ) {
- CriteriaQuery<T> cq = createQuery( clazz );
- Root<T> root = cq.from( clazz );
- CriteriaQuery<T> all = cq.select( root );
-
- return createQuery( all ).getResultList();
}
}
src/main/java/com/whitemagicsoftware/sales/service/impl/SubscriptionServiceImpl.java
import com.whitemagicsoftware.sales.Subscriber;
import com.whitemagicsoftware.sales.Subscription;
+import com.whitemagicsoftware.sales.Subscription_;
import com.whitemagicsoftware.sales.Vendor;
import com.whitemagicsoftware.sales.service.SubscriptionService;
import java.util.List;
import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
/**
* @author White Magic Software, Ltd.
*/
public class SubscriptionServiceImpl extends ServiceImpl<Subscription> implements SubscriptionService {
+
@Override
- public List<Subscription> list( Subscriber subscriber, Vendor vendor ) {
- TypedQuery<Subscription> products = createQuery( "SELECT "
- + "id, name, urlPath FROM Product "
- + "WHERE subscriber_id = :subscriber_id AND vendor_id = :vendor_id",
- Subscription.class );
+ public synchronized List<Subscription> list(
+ Subscriber subscriber,
+ Vendor vendor ) {
+ Class clazz = Subscription.class;
- products.setParameter( "subscriber_id", subscriber.getId() );
- products.setParameter( "vendor_id", vendor.getId() );
+ CriteriaBuilder builder = getCriteriaBuilder();
+ CriteriaQuery<Subscription> criteria = builder.createQuery( clazz );
+ Root<Subscription> root = criteria.from( clazz );
- return null;
+ criteria.select( root );
+ criteria.where(
+ builder.equal(
+ root.get( Subscription_.subscriberId ), subscriber.getId() ),
+ builder.equal(
+ root.get( Subscription_.vendorId ), vendor.getId() )
+ );
+
+ TypedQuery<Subscription> subscriptions = createQuery( criteria );
+
+ return subscriptions.getResultList();
}
}
src/main/sql/views/product_vw.sql
+DROP VIEW IF EXISTS product_vw;
+
+CREATE OR REPLACE VIEW product_vw AS
+SELECT
+ p.id,
+ p.name AS product_name,
+ pp.path AS product_path
+FROM
+ product p
+INNER JOIN vendor_product vp ON
+ p.id = vp.product_id
+LEFT OUTER JOIN product_path pp ON
+ pp.vendor_product_id = vp.id;
+
+ALTER TABLE product_vw
+ OWNER TO sales;
+COMMENT ON VIEW product_vw
+ IS 'Returns a list of products and paths (if applicable).';
src/main/sql/views/subscriber_vw.sql
-DROP VIEW subscriber_vw;
+DROP VIEW IF EXISTS subscriber_vw;
CREATE OR REPLACE VIEW subscriber_vw AS
src/main/sql/views/subscription_vw.sql
-DROP VIEW subscription_vw;
+DROP VIEW IF EXISTS subscription_vw;
CREATE OR REPLACE VIEW subscription_vw AS
SELECT
sp.id AS id,
sp.subscriber_id,
- sp.product_id,
- v.id AS vendor_id,
- p.name AS product_name,
- pp.path AS product_path
+ vp.vendor_id,
+ vp.product_id
FROM
- subscription sp
-INNER JOIN subscriber_vw sb ON
- sp.subscriber_id = sb.id
-INNER JOIN product p ON
- sp.product_id = p.id
-INNER JOIN vendor_product vp ON
- sp.product_id = vp.product_id
-INNER JOIN vendors() v ON
- vp.vendor_id = v.id
-LEFT OUTER JOIN product_path pp ON
- pp.vendor_product_id = vp.id
+ subscription sp,
+ subscriber_vw sb,
+ vendor_product vp,
+ product_vw p
+WHERE
+ sp.subscriber_id = sb.id AND
+ sp.vendor_product_id = vp.id AND
+ p.id = vp.product_id
ORDER BY
- vendor_id, product_id;
+ subscriber_id, product_name;
ALTER TABLE subscription_vw
OWNER TO sales;
+COMMENT ON VIEW subscription_vw
+ IS 'Returns a list of subscriptions.';
src/test/java/com/whitemagicsoftware/sales/service/impl/SubscriptionServiceImplTest.java
/**
* Tests the Subscription Service.
- *
+ *
* @author White Magic Software, Ltd.
*/
public class SubscriptionServiceImplTest extends ServiceImplTest {
public SubscriptionServiceImplTest() {
}
/**
* Ensures at least one subscriber could be retrieved from the database.
- *
- * @throws AddressException Could not convert e-mail addresses to
- * Internet Address instances.
+ *
+ * @throws AddressException Could not convert e-mail addresses to Internet
+ * Address instances.
*/
@Test
public void testSubscriptionList() throws AddressException {
List<Vendor> vendors = getVendorService().list();
List<Subscriber> subscribers = getSubscriberService().list();
- Vendor vendor = vendors.get( 0 );
Subscriber subscriber = subscribers.get( 0 );
-
- List<Subscription> subscriptions = getSubscriptionService().list( subscriber, vendor );
+ Vendor vendor = vendors.get( 0 );
+
+ List<Subscription> subscriptions = getSubscriptionService().list(
+ subscriber, vendor );
Assert.assertTrue( "Could not obtain products for vendor/subscriber pair.",

Added JPA Static Model generator. Added fluent method for Entity ID values. Closing EntityManager between usages. Using CriteriaBuilder to retrieve subscription/product information.

Author djarvis <email>
Date 2016-06-22 23:54:55 GMT-0700
Commit d52072b6a864beed184397d11d0cb474a39c0597
Parent 1228770
Delta 183 lines added, 98 lines removed, 85-line increase