Archive for November, 2014

Ubuntu 14.04 : launchpad.net NO_PUBKEY issue when running apt-get update

Launching sudo apt-get update you might get the NO_PUBKEY issue. Something like:

W: GPG-Fehler: http://ppa.launchpad.net trusty Release: Die folgenden Signaturen konnten nicht überprüft werden, weil ihr öffentlicher Schlüssel nicht verfügbar ist: NO_PUBKEY EFD5FA852F20733F

Well it´s very simple. Just execute the following (specifying the missing public key):

[email protected]:~$ sudo apt-key adv --keyserver.ubuntu.com --recv-keys EFD5FA852F20733F

And then run sudo apt-get update again. The error will disappear.

Hibernate inheritance: Discriminator Column vs Formula

Java allows you to take advantage of the domain model and think in terms of objects to elaborate technical solutions to real world problems like transferring money, buying products online and so on. These domain objects are expected to be stored and retrieved from a database, but storing the domain objects into a relational database is not so straightforward. The object-relational paradigm is mismatching, because the objects in our application are no table in a row-column format.
Hibernate allows to handle the object-relational mismatch through ihneritance strategies. The default one is the single table strategy. To achieve it you need to use discriminators.
You might add discriminator columns, but most times it´s not a good choice, especially for legacy systems, because it takes an extra column (called “d_type” as default name). So you might consider better solutions, like using the discriminator formula instead.

DiscriminatorFormula is an alternative to DiscriminatorColumn.
With DiscriminatorColumn it creates an additional column (as default called “dtype”) which contains the discriminator value.
You put the annotation in the superclass, (which maps the real table as default):

    @Entity
    @Table(name = "features")
    @DiscriminatorColumn
     public class Features{
    //valid code
    }

DiscriminatorFormula allows you to check the database row content and “select” a subclass by the discriminator value. No additional (“dtype”) column is created.
In the main class you annotate the superclass with the formula, like:

    @Entity
    @Table(name = "features")
    @DiscriminatorFormula(
    		"CASE WHEN num_value IS NOT NULL THEN 'NUMERIC' " +
	   		" WHEN txt_value IS NOT NULL THEN 'TEXT' end")
     }
     public class Features{
    //valid code
    }

In the DiscriminatorFormula you just put some pure SQL to do what you need.

You can choose one of these two options and the subclasses is exactly the same in both cases.
the subclasses are annotated java object (with @Entity), but no real table, they are just useful to map columns in the table represented by the main class.
In the subclasses you specify the discriminator value, for Example:

    @Entity
    @DiscriminatorValue('NUMERIC')
    public class NumericFeatures extends Features{

    private Double numValue;

	public Double getNumValue() {
		return numValue;
	}

	public void setNumValue(Double numValue) {
		this.numValue = numValue;
	}
   //valid code

}

In the table called “features” you have both columns “num_value” and “txt_value”, containing the corrensponding values.
With DiscriminatorColumn you would have either “NUMERIC” or “TEXT” value in the dtype column and also both the “num_value” and “txt_value” columns.

If you don´t specify the inheritance strategy the default is “SINGLE_TABLE”. the following annotation can be omitted if it´s your chosen strategy:

     @Inheritance(strategy = InheritanceType.SINGLE_TABLE)

With or without this annotation you get one table called “Features”.

MySQL CHECK constraint alternative: triggers!

Yesterday I discovered the powerful hibernate check constraint (@org.hibernate.annotations.Check) , which can be directly added in your entity class like this:

@Entity
@XmlRootElement
@Check(constraints = "age IS NOT NULL")
public class Person{

String firstname;
String lastName;
Integer age;

// valid code
}

Unfortunately, as you can read in the official MySQL docs, “the CHECK clause is parsed but ignored by all storage engines”.
Yesterday I found out that MySql 5.X doesn´t support the SQL CHECK constraint.
It means that if you are using JPA und HIBERNATE you can´t take advantage of the Check annotation!

In the project I am working on we could successfully export the schema with the maven command “hibernate4:export”. The check constraint was added in the create table statement. So if your DBMS supports it you get the job done in a very elegant way.

The way out I could find by googling a bit is not so elegant, but it allowed me to achieve the same result. I have just written a trigger, like the (simple) following:

CREATE TRIGGER check_age
BEFORE INSERT ON person
FOR EACH ROW
BEGIN
IF age is NULL
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Age cannot be null';
END IF;
END;

MySQL has been bought by Oracle. Is this silent ignoring is a strategy to make people migrate to Oracle DBMS? I am afraid it´s so. Corporation games, my friends!

Categories
Links: