| <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> |
| @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; | ||
| for( Subscription subscription : getSubscriptions( subscriber, vendor ) ) { | ||
| Scraper scraper = getScraper( vendor ); | ||
| - | ||
| + | ||
| Product product = subscription.getProduct(); | ||
| public final class Price extends BusinessEntity { | ||
| + private static final long serialVersionUID = 0L; | ||
| + | ||
| /** | ||
| * How much does a product cost? |
| */ | ||
| @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; | ||
| 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; | ||
| } | ||
| } | ||
| * The script to run for this Vendor. | ||
| */ | ||
| - @Column( name = "script" ) | ||
| + @Column( name = "script", updatable = false, insertable = false ) | ||
| private String scriptName; | ||
| /** | ||
| - * 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. |
| 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(); | ||
| } | ||
| } | ||
| 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(); | ||
| } | ||
| } |
| +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).'; | ||
| -DROP VIEW subscriber_vw; | ||
| +DROP VIEW IF EXISTS subscriber_vw; | ||
| CREATE OR REPLACE VIEW subscriber_vw AS |
| -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.'; | ||
| /** | ||
| * 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.", |
| 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 |