Zum Hauptinhalt

Optimiertes Hibernate Datatype Mapping - Gesamte Dokumentation

Ab sofort steht die gesamte Dokumentation zum RapidClipse 3 Hibernate Datatype Mapping für die Datenbanken

  • DB2
  • H2
  • MS SQL Server
  • MySQL
  • Oracle
  • PostgreSQL
  • Sybase


zur Verfügung unter: https://rapidclipse.atlassian.net/wiki/display/DOK/RapidClipse+Hibernate+Type-Mapping

Mithilfe des in RapidClipse integrierten Hibernate Imports der JBoss Hibernate Tools können Sie sich Ihr gesamtes Entity-Modell generieren lassen. Mit dem Standard-Hibernate-Import kommt es dabei jedoch meistens zu zahlreichen Datatype Mapping Problemen, die der Hibernate-Entwickler bislang selber beheben musste.

Was ist das Problem?

Durch den Hibernate Import wird für jede Datenbanktabelle eine entsprechende Entity-Klasse generiert. Die Bezeichnung des Entites wird vom Tabellennamen abgeleitet. Die Attribute eines Entities entsprechen den Datenfeldern einer Tabelle. Soweit, so gut. Problematisch wir es, wenn der Importer bestimmen muss, von welchem Datentype die einzelnen Attribute sein sollen.

Die gängigen Datenbank-Typen werden noch korrekt auf entsprechend geeignete den Java-Typen gemappt, z.B. CHAR wird zu String. Die meisten relationalen Datenbanken unterstützen jedoch sehr viele proprietäre Datentypen für die es in Java keine vergleichbaren Datentypen gibt. Datentypen wie MONEY, BINARY, IMAGE oder BLOB werden deshalb vom Hibernate Import nicht aufgelöst. Der Entwickler musste sich bislang selber entscheiden, welchen Java-Typ er wählt und musste den Javacode für das generierte Hibernate-Entity per Hand optimieren.

Beispiel für eine genrierte Hibernate-Entity-Klasse - Produkte:


package com.company.example.entities;
import static javax.persistence.GenerationType.IDENTITY;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import com.company.example.dal.ProductDAO;
import com.xdev.dal.DAO;
import com.xdev.util.Caption;
/**
 * Product
 */
@DAO(daoClass = ProductDAO.class)
@Caption("{%productname}")
@Entity
@Table(name = "PRODUCTS", schema = "PUBLIC", catalog = "NORTHWIND")
public class Product implements java.io.Serializable {
    private Integer productid;
    private Category category;
    private Supplier supplier;
    private String productname;
    private String quantityperunit;
    private BigDecimal unitprice;
    private Short unitsinstock;
    private Short unitsonorder;
    private Short reorderlevel;
    private boolean discontinued;
    private Set<Orderdetail> orderdetails = new HashSet<>(0);
    public Product() {
    }
    public Product(final String productname, final boolean discontinued) {
        this.productname = productname;
        this.discontinued = discontinued;
    }
    public Product(final Category category, final Supplier supplier, final String productname, final String quantityperunit,
            final BigDecimal unitprice, final Short unitsinstock, final Short unitsonorder, final Short reorderlevel, final boolean discontinued,
            final Set<Orderdetail> orderdetails) {
        this.category = category;
        this.supplier = supplier;
        this.productname = productname;
        this.quantityperunit = quantityperunit;
        this.unitprice = unitprice;
        this.unitsinstock = unitsinstock;
        this.unitsonorder = unitsonorder;
        this.reorderlevel = reorderlevel;
        this.discontinued = discontinued;
        this.orderdetails = orderdetails;
    }
    @Caption("Productid")
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "PRODUCTID", unique = true, nullable = false, columnDefinition = "INTEGER")
    public Integer getProductid() {
        return this.productid;
    }
    public void setProductid(final Integer productid) {
        this.productid = productid;
    }
    @Caption("Category")
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "CATEGORYID", columnDefinition = "INTEGER")
    public Category getCategory() {
        return this.category;
    }
    public void setCategory(final Category category) {
        this.category = category;
    }
    @Caption("Supplier")
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "SUPPLIERID", columnDefinition = "INTEGER")
    public Supplier getSupplier() {
        return this.supplier;
    }
    public void setSupplier(final Supplier supplier) {
        this.supplier = supplier;
    }
    @Caption("Productname")
    @Column(name = "PRODUCTNAME", nullable = false, columnDefinition = "VARCHAR", length = 40)
    public String getProductname() {
        return this.productname;
    }
    public void setProductname(final String productname) {
        this.productname = productname;
    }
    @Caption("Quantityperunit")
    @Column(name = "QUANTITYPERUNIT", columnDefinition = "VARCHAR", length = 20)
    public String getQuantityperunit() {
        return this.quantityperunit;
    }
    public void setQuantityperunit(final String quantityperunit) {
        this.quantityperunit = quantityperunit;
    }
    @Caption("Unitprice")
    @Column(name = "UNITPRICE", columnDefinition = "DECIMAL", precision = 10, scale = 4)
    public BigDecimal getUnitprice() {
        return this.unitprice;
    }
    public void setUnitprice(final BigDecimal unitprice) {
        this.unitprice = unitprice;
    }
    @Caption("Unitsinstock")
    @Column(name = "UNITSINSTOCK", columnDefinition = "SMALLINT")
    public Short getUnitsinstock() {
        return this.unitsinstock;
    }
    public void setUnitsinstock(final Short unitsinstock) {
        this.unitsinstock = unitsinstock;
    }
    @Caption("Unitsonorder")
    @Column(name = "UNITSONORDER", columnDefinition = "SMALLINT")
    public Short getUnitsonorder() {
        return this.unitsonorder;
    }
    public void setUnitsonorder(final Short unitsonorder) {
        this.unitsonorder = unitsonorder;
    }
    @Caption("Reorderlevel")
    @Column(name = "REORDERLEVEL", columnDefinition = "SMALLINT")
    public Short getReorderlevel() {
        return this.reorderlevel;
    }
    public void setReorderlevel(final Short reorderlevel) {
        this.reorderlevel = reorderlevel;
    }
    @Caption("Discontinued")
    @Column(name = "DISCONTINUED", nullable = false, columnDefinition = "BOOLEAN")
    public boolean isDiscontinued() {
        return this.discontinued;
    }
    public void setDiscontinued(final boolean discontinued) {
        this.discontinued = discontinued;
    }
    @Caption("Orderdetails")
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "product")
    public Set<Orderdetail> getOrderdetails() {
        return this.orderdetails;
    }
    public void setOrderdetails(final Set<Orderdetail> orderdetails) {
        this.orderdetails = orderdetails;
    }
}

 

Ab einer gewissen Anzahl an Datenbanktabellen und damit entsprechend vielen Entity-Klassen kommt das manuelle Mappen von Datentypen einer Sissifus-Arbeit gleich und stellt zudem eine große Fehlerquelle darstellt.


RapidClipse mappt alle Datentypen korrekt auf geeignete Java-Typen
In RapidClipse wurde der Hibernate-Import stark verbessert. RapidClipse mappt alle Datenbank-Typen automatisch auf entsprechend geeignete Java-Typen, sodass sich der Entwickler nicht mehr damit herumplagen muss.

Vollständige Dokumentation
Die Dokumentation für die dafür verwendeten Mapping-Strategien haben wir jetzt veröffentlich. Darin enthalten sind für jeden Datentyp die entsprechenden Customizer für den Hibernate-Entity-Generator sowie ein Javacode Beispiel dazu, zum Beispiel:

Datenbank: Oracle
Datentyp: NCLOB

Entity-Generator-Customizer:

visitor.addPropertyColumnDefinitionFix(new PropertyColumnDefinitionFix(
    new String[]{"NCHAR"},new String[]{"java.lang.String"},"nchar"));

Java Beispiel:
private String nchartest;

 

@Column(name = "NCHARTEST", length = 10,
            columnDefinition = "nchar")
public String getNchartest() {
    return this.nchartest;

}


Die Dokumentation zum RapidClipse Hibernate Datatype-Mapping finden Sie unter:
https://rapidclipse.atlassian.net/wiki/display/DOK/RapidClipse+Hibernate+Type-Mapping