Java tutorial
/* * Copyright 2008-2012 the original author or authors. * * 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. */ package almira.sample.domain; import java.util.Date; import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Version; import javax.validation.constraints.NotNull; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.search.annotations.DocumentId; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Index; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.Store; /** * The Catapult domain object. */ @Entity @Indexed @Table(name = "CATAPULT") // 'region' is used to register custom listener in InfinispanTracingRegionFactory // Use CacheConcurrencyStrategy.TRANSACTIONAL only with JTA @Cache(region = "catapult_cache", usage = CacheConcurrencyStrategy.NONE) @Cacheable public class Catapult implements DomainObject<Long>, Comparable<Catapult> { private static final long serialVersionUID = 1L; private static final int MAX_COLUMN_SIZE = 50; private static final int INITIAL_ODD_NUMBER = 17; private static final int MULTIPLIER_ODD_NUMBER = 31; private static TimestampGenerator now; // Override in tests to check against result set static { now = new TimestampGenerator() { @Override public Date getTime() { return new Date(); } }; } /** The id. */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @DocumentId @Column(name = "IdCatapult", nullable = false) private Long id; /** The version. */ @Version private Integer version; /** The name. */ @Field(index = Index.YES, store = Store.NO) @Column(name = "NmCatapult", unique = true, nullable = false, length = MAX_COLUMN_SIZE) private String name; /** The creation date. */ @Temporal(TemporalType.TIMESTAMP) // https://hibernate.onjira.com/browse/ANN-749 @org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.INSERT) // http://stackoverflow.com/questions/811845/setting-a-jpa-timestamp-column-to-be-generated-by-the-database @Column(name = "DtCreated", updatable = false, insertable = false, columnDefinition = "timestamp DEFAULT CURRENT_TIMESTAMP") private Date created; /** The last modified. */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "DtLastModified", columnDefinition = "timestamp") private Date lastModified; // Ideally, this would be done by a trigger (data can be changed in many ways). // See also [Bauer07] pages 183, 216, 347, 557 // http://stackoverflow.com/questions/1725699/hard-time-setting-autogenerated-time-with-hibernate-jpa-annotations /** * Update last modified. */ @PreUpdate @PrePersist public void updateLastModified() { lastModified = now.getTime(); } /** * Constructor. */ public Catapult() { // Hibernate requires an empty constructor // Also used in IndexPage to show an empty creation form } /** * Copy factory. See [Bloch08] Item 11, page 61 * * @param catapult * The catapult to copy * @return a copy of the catapult */ public static Catapult newInstance(Catapult catapult) { Catapult newCatapult = new Catapult(); newCatapult.id = catapult.getId(); newCatapult.version = catapult.getVersion(); newCatapult.name = catapult.getName(); newCatapult.created = catapult.getCreated(); newCatapult.lastModified = catapult.getLastModified(); return newCatapult; } /* (non-Javadoc) * @see almira.sample.domain.DomainObject#getId() */ @Override public Long getId() { return id; } /** * Gets the version. * * @return the version */ public Integer getVersion() { return version; } /** * Gets the name. * * @return the name */ public String getName() { return name; } /** * Sets the name. * * @param newName * the new name */ public void setName(@NotNull String newName) { this.name = newName; } /** * Get the creation date. * * @return the creation date */ public Date getCreated() { return convertDate(created); } /** * Get the last modification date. * * @return the last modification date */ public Date getLastModified() { return convertDate(lastModified); } /** * Converts <code>java.sql.Timestamp</code> to <code>java.util.Date</code>. * Here we make sure to: * <ol> * <li>protect the mutable date by making a copy</li> * <li>return a real Date object</li> * <li>return null if the date to convert is null</li> * </ol> * <br/> * https://forum.hibernate.org/viewtopic.php?f=1&t=925275&start=30 <br/> * See also [Bauer07] page 216 * * @param dateToConvert the date to convert * @return the converted date */ private Date convertDate(Date dateToConvert) { Date newDate = null; if (dateToConvert != null) { newDate = new Date(dateToConvert.getTime()); } return newDate; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return ToStringBuilder.reflectionToString(this); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public final int hashCode() { return new HashCodeBuilder(INITIAL_ODD_NUMBER, MULTIPLIER_ODD_NUMBER).append(getName()).toHashCode(); } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public final boolean equals(Object obj) { if (obj == this) { return true; } // Note that (o == null || o.getClass() != getClass()) violates Liskov // substitution principle. See [Bloch08] Item 8, page 39 if (!(obj instanceof Catapult)) { return false; } final Catapult rhs = (Catapult) obj; return new EqualsBuilder().append(name, rhs.getName()).isEquals(); } // Implementing Comparable. See [Bloch08] Item 12, page 62 /* (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public int compareTo(Catapult catapult) { return getName().compareTo(catapult.getName()); } }