I have an entity that corresponds to some table in DB
#Entity
#Table
public class MyEntity {
#Id
private Long id;
#Column
private String description;
#OneToMany
private List<Foo> foos;
...
//getters setters
...
}
And I would like to extend that entity for read-only and have additional joins to another table. I need this joins only in one case for specific read user-case:
#Entity
public class ExtendedEntity extends MyEntity {
#ManyToMany(fetch = FetchType.EAGER)
private List<Bar> bars;
}
Just using extensions will create a discriminator column in DB, which I don't need since I'm using the ExtendedEntity only for the read. I found I hack with using #DiscriminatorFormula that will be resolved to the same Integer value like this:
#DiscriminatorFormula("0")
#DiscriminatorValue("0")
public class MyEntity
#DiscriminatorValue("00")
public class ExtendedEntity extends MyEntity
But this really looks like a hack. With using #MappedSuperclass I cannot have associations, but this is the main reason I need to extend my entity.
What other options do I have and what are the best practices for this use-case?
Related
How I could join product with image as oneToMany
wihout specifying of owner's class?
To use 'image' for different owners' tables?
#Entity
#Table(name = "product")
public class Product extends BaseModel {//baseModel has 'id' column
#Column
private List<Image> images;
}
}
#Entity
#Table(name = "image")
public class Image extends BaseModel {//baseModel has 'id' column
#Column
private Object owner;
}
JPA works this way normally.
Your entity Product should be decorated like this:
#OneToMany(mappedBy="imageId")
private List<Image> images;
For any other table, you just specify mappedBy column to a proper name
Your entity Image should be decorated like this:
#ManyToOne
#JoinColumn(name="imageId", nullable=false)
private Product product
If you want to reuse some entity, i thing that it is not possible. Best think ever is to not actually use #xTox relations, they just bring pain
I have an #Entity with three fields A, B, C out of which A and B act as composite primary key. I created an #EmbeddedId class holding A and B. To ease the burden of defining getters and setters i used lombok #Data annotation.
#Entity
#Data
public class MyClass {
#EmbeddedId
private PrimaryKey id;
}
#Embeddable
#Data
public class PrimareyKey implements Serializable {
private String A;
private String B;
}
I would not like to expose that A and B are the primary key and access A and access all fields in the same way.
//Exposes primary key
myObject.getid().getA();
myObject.getid().getB();
myObject.getC();
//Hides primary key
myObject.getA();
myObject.getB();
myObject.getC();
Currently one could use #IdClass tagging each filed as #Id as suggested in this answer but if I still need to use #EmbeddedId (or any #Embedded actually) the only way (I know) to achieve this is to write ad hoc getters and setters bypassing the id variable such as
#Entity
#Data
public class MyClass {
#EmbeddedId
private PrimaryKey id;
public String A getA(){
return id.getA()
}
public String A setA(String a){
id.setA(a);
}
//same for B and any other fiels in PrimaryKey
}
This looks like a lot of boilerplate code to write and maintain.
Is there an annotation to expose #EmbeddedId getters and setters?
In MyClass, add Lombok #Delegate annotation to your PrimaryKey. It should look like:
#Entity
#Data
public class MyClass {
#Delegate
#EmbeddedId
private PrimaryKey id;
}
Then you can set/get PrimaryKey fields directly from MyClass. Here is a link for you to read more about it.
You can use the AccessLevel with #Getter and #Setter as follows:
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private PrimaryKey id;
When using #Data, you have the public access to accessors by default, and using AccessLevel.NONE will overwrite the default behaviour and will not allow to access the accessors.
Writing the case it will be more simple to explain.
I am using Seam 2.3.1 v Hibernate JPA 2.0 and in our project. I have a base Person Entity Class.
#Entity
#Name("person")
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "person")
public class Person extends BaseEntity {
private String name;
private String surName;
private String email;
private String phone;
// getter & setters
}
And I have 3 more Entity extends from Person as #Inheritance(strategy = InheritanceType.JOINED): Personel, Musteri, DisPaydas
#Entity
#Name("personel")
public class Personel extends Person {
private String appellation;
// getter & setters
}
I want to List personels, musteris and dispaydas in my bean however when I set them in my Group Entity, I want to save them as Person.
In fact in DB there is no difference between person_id and personel_id, they are same. However when I listing it, they are List<Personel>
In summary:
I want to get List<Person> from List<Personel>
or Person from Personel object.
You're going to have to define an #Id and #Column in the Person class for the person_id.
However, since the column has a different name in the child entity, you'll need to change it using an #AttributeOverride to point to the personel_id #Column.
It couldn't hurt to use a #DiscriminatorColumn in the parent and #DiscriminatorValue in the children, but I don't think Hibernate requires those.
I want to achieve something like this:
#Entity
#Table(name = "beer")
public class Beer {
#Id Long id;
String brand;
String name;
}
#Entity
public class BeerWithIngredients extends Beer {
#OneToMany(mappedBy="beer")
List<BeerIngredient> ingredients;
}
#Entity
public class BeerIngredient {
#Id Long id;
// .. whatever fields
#ManyToOne
#JoinColumn(name = "beer_id")
BeerWithIngredient beer;
}
Physically, all beer data is in one table, but I want to split it into more entities.
Please note that:
I would not like to use discriminator column in the database
There isn't a column that I could use for #DiscriminatorFormula
I do not want to embed Beer inside BeerWithIngredients, because it essentially is not a composition, but proper inheritance
Is there a way of achieving this with JPA (Hibernate)? Right now it complains about missing discriminator column, that I don't plan to provide.
Introduce a new super class RootBeer with all common beer properties. Annotate this class with MappedSuperClass. Make Beer and BeerWithIngredients inherit from RootBeer and annotate them with Entity as well as Table(name="beer").
For an example check this.
I'm trying to use hibernate to map an object like this:
#Entity
public class ParentClass {
#Id
#GeneratedValue
int Id;
#OneToMany
Map<String, ChildClass> map;
}
#Entity
public class ChildClass {
#Id
#GeneratedValue
int Id;
String text;
}
I don't want Hibernate to create a join table. I want it to add a column to the table for ChildClass. I'd also prefer not to add a field for the key in ChildClass. Ideally, when saving the object Hibernate would automatically take the key in the map and save it in the corresponding table, and do the reverse when querying. Is this possible?
If I do have to add a field to ChildClass for the key, can hibernate populate this field automatically with the key from the map? The reason I ask is because I'm getting my data from a JSON web service and using Jackson to parse it and I don't know of a way to make Jackson copy the keys to the fields in the value objects. I could write code to do that manually, but I`d rather avoid that.
Unidirectional relation without jointable:
#Entity
public class Customer implements Serializable {
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JoinColumn(name="CUST_ID")
public Set<Ticket> getTickets() {
...
}
#Entity
public class Ticket implements Serializable {
... //no bidir
}
Bidirectional without jointable:
#Entity
public class Troop {
#OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
...
}
#Entity
public class Soldier {
#ManyToOne
#JoinColumn(name="troop_fk")
public Troop getTroop() {
...
}
It's from documentation: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/
Apply these samples to your case.