I have a class Model
public abstract class Model {
#PrimaryKey
#NonNull
public String id;
}
and sub-class FooModel
#Entity
public FooModel extends Model {
String name;
}
I'd like to mark id as autoincrement but only in the child FooModel using #PrimaryKey(autoGenerate = true)
How can I go about this?
from my understanding room just as most other ORM frameworks does not realy handle class inheritance very well. you may consider defining your two classes as separate models in order to maximise on the full functionality of room .
Related
I'm using JPA JOINED inheritance strategy with 3 abstract classes and 2 concrete.
Like this (code reduced for example purpose):
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
abstract class Employee {
#Id
private Long id;
private String firstName;
private String secondName;
}
#Entity
abstract class ProjectManager extends Employee {
#OneToMany(mappedBy="manager")
private List<Developer> developers;
}
#Entity
abstract class Developer extends Employee {
#ManyToOne
#JoinColumn(name="project_manager_id")
private ProjectManager manager;
}
#Entity
class JavaProjectManager extends ProjectManager {
private String someCustomProperty;
}
#Entity
class JavaDeveloper extends Developer {
private String skill;
}
This way, JPA creates 5 tables. But one of this tables, abstract ProjectManager it is empty. I mean, ProjectManager table only have ID column due to inheritance strategy.
My question is: how I can avoid this extra table for ProjectManager abstract class but keeping the same hierarchy of classes ?
I could not remove #Entity on ProjectManager class because I still need bidirectional relationship with Developer class.
Edit:
Also, I don't want move developers OneToMany from ProjectManager to JavaProjectManager, because I have more classes that extends from ProjectManager and need to have developers.
InheritanceType.TABLE_PER_CLASS does exactly what you want.
This type only creates/uses tables for non-abstract tables.
Read more about the various types here:
https://www.thoughts-on-java.org/complete-guide-inheritance-strategies-jpa-hibernate/
I have an existing table without discriminator column and I need to map it with single table hierarchy, how to map this?
here is my table
vehicle
========
vehicle_id
manufacturer
load_capacity
passenger_capacity
I have 3 classes
Vehicle.java
vehicleId;
manufacturer;
TransportationVehicle.java
loadCapacity;
PassengerVehicle.java
passengerCapacity;
If you have no discriminator, then you need another condition to distinguish TransportationVehicle and PassengerVehicle. I guess in your case you could use:
TransportationVehicle: loadCapacity IS NOT NULL
PassengerVehicle: passengerCapacity IS NOT NULL
As JPA inheritance always needs a discriminator, you will have to use #MappedSuperclass and two #Entity classes with a corresponding #Where annotation:
#MappedSuperclass
public abstract class Vehicle {
#Id
private Long vehicleId;
private String manufacturer;
}
#Entity #Where(clause = "loadCapacity IS NOT NULL")
public class TransportationVehicle extends Vehicle {
private int loadCapacity;
}
#Entity #Where(clause = "passengerCapacity IS NOT NULL")
public class PassengerVehicle extends Vehicle {
private int passengerCapacity;
}
Major disadvantage of this approach compared with real JPA inheritance: You can't reference the mapped superclass in JPA - neither in queries (SELECT v FROM Vehicle v) nor in another entity (#OneToOne Vehicle vehicle).
One way to do it is use #MappedSuperclass on the Vehicle class and then map TransportationVehicle and PassengerVehicle to the same table.
This way you will inherit the mapped fields from Vehicle without having to map it as an entity.
Is there any reason why shouldn't all my entities be subclasses of one generic ModelEntity object?
#Entity
public class ModelEntity {
#Id Long id;
}
#Subclass
public class User extends ModelEntity {
#Index
String username;
}
The advantages are clear: there is code common to all entities (like id, date, getKey)
Can you think of disadvantages?
It can be helpful to have a common base class, but you almost certainly do not want to make it part of a polymorphic entity hierarchy. Don't use #Subclass for this purpose; you don't need it:
public class ModelEntity {
#Id Long id;
}
#Entity
public class User extends ModelEntity {
#Index
String username;
}
Well, one of the great advantages of the jpa abstractions is to have insulation between the persistence layer and business logic. If you use an hidden id for all your entities you are giving up on that.
For example you could have a value object with your implementation so that you are actually hiding the #Id part of your entity. You could the use a completely different #Id for "real" entities.
I have the following setup with Spring Data JPA and Hibernate as the persistence provider. All of my entities inherit from a base class
#MappedSuperclass
public class BaseEntity {
#Id
private id;
#Version
private String version;
//more common fields
}
For example:
#Entity
public class Foo extends BaseEntity {
}
This leads to a primary key column with name "ID" to be generated on the "FOO" table. I would like to change the naming of the primary key column. It should reflect the name of class or table. So it should be "FOO_ID" instead of just "ID".
I know that I could do this statically by using #Column(name = "FOO_ID"). But that would mean I have to do this for every Entity. Is there a more dynamic way to achieve this?
I know this is an old question, but stumbled across this looking for an answer... Eventually found this solution elsewhere:
#Entity
#AttributeOverride(name="id", column=#Column(name="FOO_ID"))
public class Foo extends BaseEntity {
}
All your subClasses will have the same ID column name because of the inheritance, you can specify a common id colum name for all subClasses in the Base entity Class
Why use inheritance then? Just do it without inheritance.
You could use getters/setters to rename your fields
Ex:
class Foo {
private Long id;
public Long getFooId() {
return this.id;
}
public void setFooId(Long fooId) {
this.id = fooId;
}
}
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.