I have a simple JOINED hierarchy of documents:
Code:
CREATE TABLE Documents
(
id INTEGER NOT NULL,
discriminator ENUM('official','individual','external') NOT NULL,
file_name VARCHAR(200) NOT NULL,
PRIMARY KEY (id)
);
CREATE SystemDocuments
(
id INTEGER NOT NULL,
binary_data BLOB NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES Documents (id)
);
CREATE ExternalDocuments
(
id INTEGER NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES SystemDocuments (id)
);
As you can see all the sub tables do is share the same ID from the Documents table. Other than that `SystemDocuments` adds a `binary_data` column and `ExternalDocuments` adds no new properties. (Also note there are two other concrete sub tables in the hierarchy denoted by `'official'` and `'individual'` which are of no relevance here.)
Here are the mappings for the above tables:
Document.java:Code:
@Entity
@Table(name = "Documents")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
//@DiscriminatorOptions(force = true) // <-- Hibernate 4-specific annotation not inserting discriminator values
public abstract class Document implements Serializable
{
@Id
@Column
protected Integer id;
@Column(name = "file_name")
protected String fileName;
...
}
SystemDocument.java:Code:
@Entity
@Table(name = "SystemDocuments")
public abstract class SystemDocument extends Document
{
@Lob
@Column(name = "binary_data")
protected byte[] binaryData;
...
}
ExternalDocument.java:Code:
@Entity
@Table(name = "ExternalDocuments")
@DiscriminatorValue(value = "external")
public class ExternalDocument extends SystemDocument
{
...
}
The latter class is supposed to be mapped to the Documents' discriminator column value `'external'`. When finding entities via EntityManager.find the discriminators are returned correctly, but that's because the discriminators of my test data have been INSERTed into the DB correctly.
Now I'm using the following code to insert new documents/files into the system via JPA and a file uploader:
Code:
...
UploadedFile uf = event.getUploadedFile();
// set ID, file name, and binary data
ExternalDocument detachedExternalDocument =
new ExternalDocument(1234567, uf.getName(), uf.getData());
docService.create(detachedExternalDocument);
When inspecting the DB I can see that Hibernate does
not insert the `'external'` discriminator value into the `Documents` table's `discriminator` column but uses 'official' all the time. This leads to a inconsistent data and is all but expected.
Am I using Hibernate/JPA incorrectly? Is it a bug? Is there some config option?
There have been issues about this in the past, see
https://hibernate.onjira.com/browse/ANN-140 and more recently for Hibernate 4
https://hibernate.onjira.com/browse/HHH-4358, so chances are it's supposed to work that way.
I then found
http://docs.jboss.org/hibernate/core/4. ... tions.html in the current Hibernate 4 API Docs, but it doesn't work (see @DiscriminatorOptions at the Document class).
How can I get Hibernate 4 to insert the discriminators
using raw annotations?
Note: I don't want to map the discriminator column as a regular @Column.
Thanks
Karsten