package com.demo.demo.model.obj.demo;
import com.demo.demo.model.obj.demo.Line;
import com.demo.demo.model.obj.demo.iface.IOrder;
import com.demo.demo.services.data.DataLayerDemoImpl;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.proxy.HibernateProxy;


/** 
 * Object mapping for hibernate-handled table: order.
 * @author autogenerated
 */

@Entity
@Table(name = "order", catalog = "demo")
public  class Order implements Cloneable, Serializable, IOrder {

    /** Serial Version UID. */
    private static final long serialVersionUID = -559029078L;


    /** Field mapping. */
    private Customer customer;
    /** Field mapping. */
    private Set<Line> lines = new HashSet<Line>();

    /** Field mapping. */
    private Long id = 0L; // init for hibernate bug workaround
    /** Field mapping. */
    private Date orderDate;
    /**
     * Default constructor, mainly for hibernate use.
     */
    public Order() {
        // Default constructor
    } 

    /** Constructor taking a given ID.
     * @param id to set
     */
    public Order(Long id) {
        this.id = id;
    }
    
    /** Constructor taking a given ID.
     * @param customer Customer object;
     * @param id Long object;
     * @param orderDate Date object;
     */
    public Order(Customer customer, Long id, Date orderDate) {

        this.customer = customer;
        this.id = id;
        this.orderDate = orderDate;
    }
    
 


    /**
     * Return the value associated with the column: customer.
     * @return A Customer object (this.customer)
     */
    @ManyToOne( cascade = CascadeType.ALL, fetch = FetchType.LAZY )
    @JoinColumn(name = "customer_id" )
    public Customer getCustomer() {
        return this.customer;
    }
    

  
    /**  
     * Set the value related to the column: customer.
     * @param customer the customer value you wish to set
     */
    public void setCustomer(final Customer customer) {
        this.customer = customer;
    }


    /**
     * Return the value associated with the column: line.
     * @return A Set&lt;Line&gt; object (this.line)
     */
    @Column( name = "order_id", nullable = false  )
    @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "order"  )
    public Set<Line> getLines() {
        return this.lines;
    }
    
    /**
     * Adds a bi-directional link of type Line to the lines set.
     * @param line item to add
     */
    public void addLine(Line line) {
        this.lines.add(line);
        line.setOrder(this);
    }

  
    /**  
     * Set the value related to the column: line.
     * @param line the line value you wish to set
     */
    public void setLines(final Set<Line> line) {
        this.lines = line;
    }


    /**
     * Return the value associated with the column: id.
     * @return A Long object (this.id)
     */
    @Id 
    @Column( name = "order_id", nullable = false  )
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return this.id;
    }
    

  
    /**  
     * Set the value related to the column: id.
     * @param id the id value you wish to set
     */
    public void setId(final Long id) {
        this.id = id;
    }


    /**
     * Return the value associated with the column: orderDate.
     * @return A Date object (this.orderDate)
     */
    @Column( name = "order_date", nullable = false  )
    public Date getOrderDate() {
        return this.orderDate;
    }
    

  
    /**  
     * Set the value related to the column: orderDate.
     * @param orderDate the orderDate value you wish to set
     */
    public void setOrderDate(final Date orderDate) {
        this.orderDate = orderDate;
    }


   /**
    * Deep copy.
    * @return cloned object
    * @throws CloneNotSupportedException on error
    */
    @Override
    public Order clone() throws CloneNotSupportedException {
        super.clone();  // keep hierarchy
        final Order copy = new Order();

        copy.setCustomer(this.getCustomer());
        copy.getLines().addAll(this.getLines());
        copy.setId(this.getId());
        copy.setOrderDate(this.getOrderDate());
        return copy;
    }


    /** Provides toString implementation.
     * @see java.lang.Object#toString()
     * @return String representation of this class.
     */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        
        sb.append("id: " + this.getId() + ", ");
        sb.append("orderDate: " + this.getOrderDate());
        return sb.toString();       
    }

    
    /** Equals implementation. 
     * @see java.lang.Object#equals(java.lang.Object)
     * @param aThat Object to compare with
     * @return true/false
     */
    @Override
    public boolean equals(final Object aThat) {
        Object unproxyThat = aThat;
        
        if ( this == aThat ) {
             return true;
        }
        
        if (aThat instanceof HibernateProxy) {
            // narrow down the proxy to the class we are dealing with.
            try {
                unproxyThat = DataLayerDemoImpl.getInstance().loadOrder(((Order)aThat).getId());
            } catch (ClassCastException e) {
                return false;
            }
        }
        if ((aThat == null) || ( !(unproxyThat.getClass().equals(this.getClass())))) {
             return false;
        }
        
        final Order that = (Order) unproxyThat;
        boolean result = true;
        result = result & (((this.getOrderDate() == null) && (that.getOrderDate() == null)) || (this.getOrderDate() != null  && this.getOrderDate().equals(that.getOrderDate())));

        return result;
    }


    
    /** Calculate the hashcode.
     * @see java.lang.Object#hashCode()
     * @return a calculated number
     */
    @Override
    public int hashCode() {
        int result = 0;
        result = 26 * result + (this.getCustomer() == null || this.getCustomer().getId() == null ? 0 : this.getCustomer().getId().hashCode());
        result = 26 * result + (this.getOrderDate() == null ? 0 : this.getOrderDate().hashCode());

        return result;  
    }
}