Display object values ​​from third-party libraries

I have the following object that I need to store in a relational database via Hibernate annotations :

@Entity @Table(name="fizzes") public class Fizz { @Id @GeneratedValue @Column(name="fizz_id") private int id; @Column(name="fizz_wooz") private String wooz; // ??? here I am unsure! private Buzz buzz; // Constructor, getters/setters down here, etc... } public class Buzz { private int jupiter; private String neptune; // Constructor, getters/setters down here, etc... } 

The problem with Buzz is this:

  • I do not want this to be his own entity / table. I want this to be an "object / value type" that maps to the fizzes table (by adding columns to it).
  • Buzz is a third-party library, so I cannot change it.

Therefore, the end result in the form of a table I'm looking for is:

 [fizzes] table ============== fizz_id, PRIMARY KEY AUTO INCREMENT fizz_wooz, NVARCHAR(50) NOT NULL fizz_buzz_jupiter, INT NOT NULL fizz_buzz_neptune, NVARCHAR(100) NOT NULL 

How can I get Hibernate to do this annotation-based mapping when I cannot change Buzz ?

+5
source share
2 answers

What you are looking for is called Embeddable .

 @Entity public class Fizz { ... @Embedded private Buzz buzz; } 

And you can define a mapping file only for Buzz :

 <entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"> <embeddable class="...Buzz"> <attributes> <basic name="jupiter"><column name="fizz_buzz_jupiter"/></basic> <basic name="neptune"><column name="fizz_buzz_neptune"/></basic> </attributes> </embeddable> </entity-mappings> 

You can include this mapping file in your persistence.xml :

 <persistence-unit> <mapping-file>.../orm.xml</mapping-file> </persistence-unit> 

If you really want to use annotations for Buzz : you cannot define annotations for other classes. This is the meaning of annotations: they are embedded and belong to their class. Otherwise, there would be no benefit compared to mapping files ...

But you can extend Buzz and use one that has access to properties:

 @Entity public class Fizz { ... @Embedded private BuzzExtension buzz; } @Embeddable @Access(AccessType.PROPERTY) public class BuzzExtension extends Buzz { @Column(name="fizz_buzz_jupiter") public int getJupiter() { return super.getJupiter(); } @Column(name="fizz_buzz_neptune") public String getNeptune() { return super.getNeptune(); } } 

Only flaw: you cannot use instances of Buzz in Fizz .

+7
source

I think you want the properties of the Buzz object to be present in the Fizz object, which means that both the Buzz and Fizz properties must be present as columns in the same fizzes table.

So you need to extend the Fizz object where Buzz will be annotated as @MappedSuperClass

 @Entity @Table(name="fizzes") public class Fizz extends Buzz { // Fizz properties // No need to add Buzz as a field } @MappedSuperclass public class Buzz { // Buzz properties } 

If you have not added the @MappedSuperClass annotation, you cannot achieve this. Although Buzz expands to Fizz , Buzz fields will not be recognized by Hibernate, since Hibernate only reflects in the fields present in Fizz , but not in the fields present in the extended Buzz class unless you specify the @MappedSuperClass annotation. MappedSuperclass will show that sleep also uses reflection in the fields of the Buzz object.

+1
source

Source: https://habr.com/ru/post/1233839/


All Articles