I have an abstract class annotated as #MappedSuperclass. This class defines attributes common to all JPA classes such as Id.
I would like to override Id attribute mapping defined in the abstract super class and assign a sequence generator. Is it possible to override Id attribute mapping and assign a different sequence generator in JPA 2.x?
One thing that pops into my head is to use two base classes; one without the ID property and one that explicitly adds the ID property. Then you have freedom if you extend the one with ID or the one without ID so you can provide one specifically in the entity. Code skeleton without annotations:
public abstract class _Base {
// common properties here
}
public abstract class _BaseWithId extends _Base {
private Long id;
}
public class MyEntity1 extends _BaseWithId {
}
public class MyEntity2 extends _Base {
private Long id;
}
Related
Trying to make a MapStruct implementation where I have a "parent"-object like this:
public abstract class Parent {
private String id;
}
Then I have children with a whole bunch of more attributes such as:
public class ChildA extends Parent{
private String name;
//And so on...
}
public class ChildB extends Parent{
private String address;
//And so on...
}
How do I represent this data-structure in MapStruct mappers? I only want to map the children and not the parent. I have successfully made a mapper to map a child with an abstract class, but I can't get the "parent" mapping to tag along without explicitly stating it inside the child-mappers.
Is there a way I can do something like:
#Mapping(source = "id" target = "targetId")
In a parent mapper, and then inherit that mapping statement to the children? I don't want the parent to have a mapper on its own, I just want it to hold that mapping statement to reduce redundancy.
I would love to extend my abstract child-mapper class with a parent class and then simply inherit. Is this possible?
I have an abstract class Entity and then multiple instance can extend Entity
like
A extends Entity {
}
B extends Entity {
}
Now all the entity needs to have entityId
So should I have entityId as a private field in Entity and set it via the constructor, or as a protected member in Entity, so that the subclasses can access it directly?
First off, you can rename entityId as id as it is obviously the id of the entity. It is a member of Entity.
I will assume that id cannot be changed and as such it should be private, set only once and only in the constructor. The class should have a public getId() method. This way other objects can access it in addition to subclasses.
With this implementation id can't be changed accidentally by subclasses.
You should have entityId as part of entity base type as protected.
From a design perspective, entityID should be part of the entity. So, place it in Entity class and make it protected so that its subclasses can access it.
Use protected, So that all the inherited classes can access it.
If the base class constrctor accepts value for entity id, like follows
class Entity
{
protected int EntityId;
public Entity(int _entityId)
{
EntityId=_entityId;
}
}
Then you can use "super" function to call base class constructor from derived class constructor
class ExtendedEntity extends Entity
{
public ExtendedEntity (int _entityId)
{
super(_entityId); // calling base class constructor
}
}
This is probably the main reason why protected members exist. Basically it's the same as private but with the exception that it appears public to your subclasses and to classes in the same package (if that's a concern, go with private).
Now, that's the general theory for instance variables in an inheritance structure, but as others have pointed out, as this seems to be about an ID field, it's still better to make it private and maybe also final. Then write a public getter method, except if no one should be able to get the ID except from the subclasses, then make it protected.
Make it a private field in Entity and make (protected) accessors (getter/setter) so that subclasses have access to the field via the setter or getter (basic OO principles)
You can also write a specific constructor for the Entity class, taking an id as argument and call this constructor from the extending classes. By doing so, your subclasses are always forced to set an id.
Eg.
public class Entity {
private int id;
public Entity(int id) {
setId(id);
}
protected int getId() {
return id;
}
protected void setId(int id) {
this.id = id;
}
}
public class A extends Entity {
public A(int id) {
super(id);
}
}
I have a simple inheritance model:
public abstract class Base {
int id;
string name;
}
public class Derived1 extends Base {
int valueD1;
}
public class Derived2 extends Base {
int valueD2;
}
How should I map the classes (with JPA annotations) so that I have separate tables for Derived1 and Derived2 (Table per concrete class), and no table for Base.
Should I use #MappedSuperclass, or #Embeddable (and skip inheritance), or #Inheritance?
Use #MappedSuperclass, and define distinct tables for each entity, IMHO,
But it depends on if you will most likely query for the parent class or if you use both derived entities for themselves, without having the need to query two tables.
I have many entities with common properties. There is no xml schema, so I write jaxb entities on my own.
abstract class SuperEntity {
protected String id;
protected String name;
#XmlElement
public void setId() { .. sets Id .. }
#XmlElement
public void setName() { .. sets name .. }
}
// id and name are null after deserialization .. they are completely ignored
// there are other entities such as this, I don't want to repeat my code
#XmlRootElement
#XmlSeeAlso({SuperEntity.class})
class SpecificEntity extends SuperEntity {
protected String specificField;
#XmlElement
public void setSpecificField() { .. sets specific field .. }
}
SuperEntity is not deserialized (unmarshelled) at all, leaving fields null. If i copy fields and setters from superclass to specific class, it works, but I dont want to just copy that code to every child entity. Thank you for your help.
Change the class definitions to
#XmlRootElement
#XmlSeeAlso({SpecificEntity.class})
abstract class SuperEntity {
#XmlRootElement
class SpecificEntity extends SuperEntity {
When JAXB is processing a class model it will also process super classes (the ones not annotated with #XmlTransient). By default it won't process subclasses. The #XmlSeeAlso needs to go on the super class and reference the subclasses.
I have problem with adding index. I use hibernate with annotation driven configuration.
I have something like this:
#MappedSuperclass
public abstract class BaseEntity {
#Id
private String id;
private String profileId;
...
//getters and setters
}
and several child classes
#Table(name="note")
public abstract class Note extends BaseEntity{
//different fields
}
#Table(name="message")
public abstract class Message extends BaseEntity{
//different fields
}
I want to add index to field "profileId" in class BaseEntity. But if I do so, with annotation #Index(name="profileid_index"), it creates only for table "note", and fails on "message", because index "profileid_index" already exist.
I did not find way, how to make hibernate generate unique index names. Or may be someone knows another solution how to index field in parent class.
Did you have a look on #Tables annotation: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/ ?
You can do stuff like:
#Tables(value={#Table(appliesTo="table1", indexes={#Index(name="index1", columnNames={"column1", "column2"})}),
#Table(appliesTo="table2", indexes={#Index(name="index1", columnNames={"column1", "column2"})})})
Should help in your case if you put this annotation to your #MappedSuperclass, although I don't know if there is a more cleaner solution
Being more precise, you could try for your case:
#Tables(value={#Table(appliesTo="note", indexes={#Index(name="index_profile_id1", columnNames={"profileId"})}),
#Table(appliesTo="message", indexes={#Index(name="index_profile_id2", columnNames={"profileId"})})})