Base entity class in JPA

hibernate

In Hibernate/JPA entities there are repeated fields and methods. Don’t repeat yourself and write a base class with @MappedSuperclass.

BaseEntity one: Minimal options

Common fields:

id: Table Id Column, Auto Increment. In entity model with @Id annotation.

version: Version column for Optimistic Lock has default ’0′ in table and managed from your database and EntityManager. In entity model with @Version annotation.

Common methods:

hashCode() and equals() very important. If you do not implement the methods you get problems later.

toString():I am using entity values for display e.g. customer.getFirstname(). It is more flexible for Swing, JavaFX or JSF components.


package com.devsniper.entitydemo.model;

import java.io.Serializable;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

/**
 * Base Entity
 *
 * @author cem ikta
 */
@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id", nullable = false, columnDefinition = "BIGINT UNSIGNED")
    protected Long id;

    @Column(name = "version")
    @Version
    private Long version;

    public Long getId() {
        return id;
    }

    public Long getVersion() {
        return version;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (this.getId() != null ? this.getId().hashCode() : 0);

        return hash;
    }

    @Override
    public boolean equals(Object object) {
	if (this == object)
            return true;
        if (object == null)
            return false;
        if (getClass() != object.getClass())
            return false;

        BaseEntity other = (BaseEntity) object;
        if (this.getId() != other.getId() && (this.getId() == null || !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return this.getClass().getName() + " [ID=" + id + "]";
    }
}

BaseEntity two: with audit informations

Common fields: createdBy, createdAt, updatedBy, updatedAt

It is sometimes important to know when and by whom the data were saved. I save creation date, modification date and user informations in table. I have String for user informations, I save only username without foreign key, then I have no relations with user table. With @PrePersist and @PreUpdate you don’t need to set the date manual every time. Set the user informations(createdBy and updatedBy) in your controllers not in models. Business logic must always remain in the right place.

package com.devsniper.entitydemo.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Size;

/**
 * Base Entity Audit
 *
 * @author cem ikta
 */
@MappedSuperclass
public abstract class BaseEntityAudit extends BaseEntity {

    @Column(name = "created_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Size(max = 20)
    @Column(name = "created_by", length = 20)
    private String createdBy;

    @Column(name = "updated_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;

    @Size(max = 20)
    @Column(name = "updated_by", length = 20)
    private String updatedBy;

    public Date getCreatedAt() {
            return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
            this.createdAt = createdAt;
    }

    public String getCreatedBy() {
            return createdBy;
    }

    public void setCreatedBy(String createdBy) {
            this.createdBy = createdBy;
    }

    public Date getUpdatedAt() {
            return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
            this.updatedAt = updatedAt;
    }

    public String getUpdatedBy() {
            return updatedBy;
    }

    public void setUpdatedBy(String updatedBy) {
            this.updatedBy = updatedBy;
    }

    /**
     * Sets createdAt before insert
     */
    @PrePersist
    public void setCreationDate() {
        this.createdAt = new Date();
    }

    /**
     * Sets updatedAt before update
     */
    @PreUpdate
    public void setChangeDate() {
        this.updatedAt = new Date();
    }

}

Sample usage of EntityBaseAudit:

If you use your table id columns with table name prefix e.g customer_id then use @AttributeOverride. Without prefix you remove @AttributeOverride.

@Entity
@Table(name = "customers")
@AttributeOverride(name = "id", column = @Column(name = "customer_id",
        nullable = false, columnDefinition = "BIGINT UNSIGNED"))
public class Customer extends BaseEntityAudit {

    // fields without id column ...

    public Customer() {
    }

    // getter and setter ...

}

Less Css Framework in JSF 2

less cssLESS is the dynamic stylesheet language. Twitter Bootstrap uses it internally. It is similar in structure Saas. An introduction to LESS and comparison to Sass can be found here.

I wanted to use LESS in JSF 2. LESS installation is easy but in JSF 2 necessary to make settings.

I have resources folder in the root of my web application (same folder level with “WEB-INF” folder). A tutorial Resources in JSF 2 can be found here.

All my css and javascripts are under the resources.

LESS installation in html:

<link rel="stylesheet/less" type="text/css" href="styles.less">
<script src="less-1.3.0.min.js" type="text/javascript"></script>



I am writing with JSF 2 tags in index.xhtml:

<h:outputStylesheet name="common.less" library="css" />
<h:outputScript name="less-1.3.0.min.js" library="javascript" target="body" />



Target parameter gets “head” oder “body”, better use “body” parameter then less-1.3.0.min.js rendered in body.

But in JSF 2 does not work. LESS need rel="stylesheet/less" but h:outputStylesheet gets rel="stylesheet" from common.less. And common.less file is not rendered as css file.

If your servlet-mapping as below:

<servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<!-- use in index.xhtml -->
<link rel="stylesheet/less" href="/PROJECTNAME/faces/javax.faces.resource/common.less?ln=css" />



if your servlet-mapping with xhtml:

<servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- use in index.xhtml -->
<link rel="stylesheet/less" href="/PROJECTNAME/javax.faces.resource/common.less.xhtml?ln=css" />



I am using with *.xhtml format, all together:

<!-- in web.xml -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>


<!-- in index.xhtml -->
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>
<!-- TODO use in production compiled css file from less file -->
<link rel="stylesheet/less" href="/PROJECTNAME/javax.faces.resource/common.less.xhtml?ln=css" />
<!-- first less file than less javascript -->
<h:outputScript name="less-1.3.0.min.js" library="javascript" target="body" />
</h:head>



If it works then your common.less file rendered as Css in index.xhtml.

If you get mime type warning for LESS file in Glassfish as below:

WARNING: JSF1091: No mime type could be found for file common.less. To resolve this, add a mime-type mapping to the applications web.xml.

Add LESS file mime type in web.xml in your project.

<mime-mapping>
  <extension>less</extension>
  <mime-type>stylesheet/less</mime-type>
</mime-mapping>



LESS file support in Netbeans 7.1.2:

LESS syntax is so similar to CSS. You can add new file extension in Tools > Options > Miscellaneous > Files, Click new file extension as less and Associated File Type text/x-css


LESS file support in Eclipse Indigo:

Preferences > General > Content Types > Text > CSS, and add Content type:*.less then

Preferences > General > Editors > File Associations, click on Add button and set File type: *.less, and then in the Associated editors box below set the CSS Editor as default.

Ubuntu 12.04 – install sun jdk 6-7

java logo

Ubuntu GNU/Linux 12.04 LTS (Precise Pangolin) released. I wanted to manually install the Sun JDK 6 and 7 on Ubuntu.

Updated for Ubuntu GNU/Linux 13.04 (Raring Ringtail).

Updated for Ubuntu GNU/Linux 12.10 (Quantal Quetzal).

Installing Sun JDK 6 on Ubuntu 12.04 / 12.10 / 13.04:

  • Make the bin file executeable:
chmod +x jdk-6u32-linux-x64.bin
  • Extract the bin file:
./jdk-6u32-linux-x64.bin
  • For Ubuntu 13.04: There is no longer a jvm folder in /usr/lib, therefore create jvm folder
sudo mkdir /usr/lib/jvm
  • Move extracted folder to this location:
sudo mv jdk1.6.0_38 /usr/lib/jvm/jdk1.6.0_38
  • Install new java source in system:
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_38/bin/javac 1
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_38/bin/java 1
sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.6.0_38/bin/javaws 1
  • Choose default java:
sudo update-alternatives --config javac
sudo update-alternatives --config java
sudo update-alternatives --config javaws
  • java version test:
java -version
  • Verify the symlinks all point to the new java location:
ls -la /etc/alternatives/java*
  • Enable Java plugin for Mozilla Firefox (even for Chrome)
#for 64-Bit jdk
sudo ln -s /usr/lib/jvm/jdk1.6.0_38/jre/lib/amd64/libnpjp2.so /usr/lib/mozilla/plugins
#for 32-Bit jdk
sudo ln -s /usr/lib/jvm/jdk1.6.0_38/jre/lib/i386/libnpjp2.so /usr/lib/mozilla/plugins

Installing Sun JDK 7 on Ubuntu 12.04 / 12.10 / 13.04:

  • Download the sun jdk 7 tar file from here
  • Extract the tar file:
tar -xvzf jdk-7u11-linux-x64.tar.gz
  • For Ubuntu 13.04: There is no longer a jvm folder in /usr/lib, therefore create jvm folder
sudo mkdir /usr/lib/jvm
  • Move extracted folder to this location:
sudo mv jdk1.7.0_11 /usr/lib/jvm/jdk1.7.0_11
  • Install new java source in system:
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.7.0_11/bin/javac 1
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.7.0_11/bin/java 1
sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.7.0_11/bin/javaws 1
  • Choose default java:
sudo update-alternatives --config javac
sudo update-alternatives --config java
sudo update-alternatives --config javaws
  • java version test:
java -version
  • Verify the symlinks all point to the new java location:
ls -la /etc/alternatives/java*
  • Enable Java plugin for Mozilla Firefox (even for Chrome)
#for 64-Bit jdk
sudo ln -s /usr/lib/jvm/jdk1.7.0_11/jre/lib/amd64/libnpjp2.so /usr/lib/mozilla/plugins
#for 32-Bit jdk
sudo ln -s /usr/lib/jvm/jdk1.7.0_11/jre/lib/i386/libnpjp2.so /usr/lib/mozilla/plugins

Update: I have added Java Web Start configuration (Thanks Jack).

Update: I have added Java Plugin configuration for Mozilla Firefox even for Chrome (Thanks shetty).

Update: JAVA_HOME configuration: Some tools require JAVA_HOME variable. You can set JAVA_HOME in Ubuntu so simple: Edit the file .bashrc under your home directory and add the following lines: (if .bashrc is hidden, click in Nautilus Menu View > Show Hidden Files)

export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_11 or /usr/lib/jvm/jdk1.6.0_38
export PATH=$JAVA_HOME/bin:$PATH

or add this JAVA_HOME=/usr/lib/jvm/jdk1.7.0_11 in /etc/environment with sudo gedit /etc/environment