Inheritance in entities, using objectbox - java

In my code I put some base fields in base abstract class BaseEntity:
public abstract class BaseEntity {
#Id
private long id;
public BaseEntity() {
}
public BaseEntity(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
So, in child class User I am not define an id field:
#Entity
public class User extends BaseEntity {
private String name;
private String login;
private String gender;
private String email;
private String phoneNumber;
private Date registrationDate;
private Date lastActivityDate;
private long systemId;
public User() {
}
...Getters and Setters
}
because it defined in superclass. I don't want to create in every class an id field, and don't want to persist in database BaseEntity class. And I get an error:
Error:[ObjectBox] Code generation failed: No ID property found for Entity User (package:...)
How can I use objectbox with an inheritance?

Polymorphism of entities is not supported at this time, but there is a feature request.
If it helps, you can go for an interface. E.g.:
public interface BaseEntity {
long getId();
}
Note: you could have a setter for the ID, but my personal advice would be to have the id field package private (so ObjectBox has access from generated classes) and not have a setter because it would suggest it's OK to change the ID at any time.
Update: ObjectBox 1.4 introduced entity inheritance (non-polymorphic).

#Oleg Objectbox don't support inheritance in entity class as it will map every entity to a separate table in db and use this #Id variable as unique id to identify a row(entity instance) in that table. Thus #Id variable is must for every entity class.
In general,
for each for Child class to access Parent class variables it have to be either protected or public but in your id is private so change it to either protected it will work.
protected long id;
if you mark it is as protected only the parent and its child class can access it and when you mark it as public any class can access it.
marking it as private means only parent class can access it

Related

How can I properly set up my Spring persistance models so that specific models correctly subclass a "generic" model?

I would like to have different kinds of "alerts" in my application, so I thought I would create an abstract class for general Alerts and have my specific alerts extend that.
#MappedSuperclass
public abstract class Alert<A extends Serializable> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#CreatedDate
#Temporal(TIMESTAMP)
protected OffsetDateTime dateCreated;
#LastModifiedDate
#Temporal(TIMESTAMP)
protected OffsetDateTime dateModified;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Now, for example, one of my specific alerts:
#Entity
public class SpecificAlertAlpha extends Alert<Serializable> implements Serializable{
private String description;
private int someNumber;
private boolean someYesNo;
}
In my database, I do not want a generic "Alerts" table, instead I want tables for each of the subclass alerts.
I have seen several examples through my searches, but nothing that seems to reach out and grab me as far as what I need. In one example, the subclass that extends the superclass has Long as the type in angle brackets, but I am not sure what that is for. I thought maybe the ID, but I am now lost in confusion.
How can I set up my models so that they can do what I would like them to do?

How to get the value of the lazy Hibernate field through reflection

I found similar questions, but they did not answer my question.
I have two entities with a many-to-one relationship - unidirectional.
But most importantly, the relationship is lazy. Because it is correct to use a lazy connection, everyone knows it.
Code:
#Entity
public class User implements BaseEntity {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String name;
#ManyToOne(fetch = FetchType.LAZY)
private City city;
}
#Entity
public class City implements BaseEntity {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String name;
}
interface BaseEntity {
void setId(Long id);
Long getId();
}
I wrote a method that allows you to search by the transferred fields of the entity.
An example of how this works:
public class Search<T extends BaseEntity> {
public List<T> getByFields(T entity, List<FieldHolder> data) {
// create criteria with passed field name and value by reflection
}
}
class FieldHolder {
private String fieldName;
private Object value;
/**
* "true" - means that the field "value" contains id related object
* "false" - elementary type like: String, Wrapper, Primitive
*/
private boolean isRelationId;
}
The problem is that problems start when you need to search and related objects - by creating related queries.
The following entry is used to send the associated field: "city.id" and the problem is that when I transfer the essence of the related object (City) it is in a proxy and I cannot get id by reflection from City.
My function works perfectly if you specify:
#ManyToOne(fetch = FetchType.EAGER)
private City city;
But it will greatly affect performance, since I have a lot of related objects. Therefore, I want to solve this problem for a lazy load.
I know that this is not an easy task. But perhaps there is some opportunity to somehow get around this problem.

Identify primary key in hibernate

Is there any way to identify the Primary key of an entity class in my JSP page.
For Eg: If i call a function, i need to get back the #ID parameter declared in the entity class as return.
It's very obvious how to do this. Assuming that all your entities will look like about the following:
#Entity
public class MyEntity implements Serializable {
private Long id;
#Id
#GeneratedValue(...)
public Long getId() {
}
public void setId(Long id) {
return id;
}
}
you simply write myEntity.getId().

Hibernate. Generic Composite PK issue

I have an issue with composite primary key in Hibernate.
Example:
I have a class that represents base primary key for all instances of this.
public abstract class PrimaryKey implements Serializable { /* ... */ }
It has nothing but implements java.io.Serializable interface and can be used in generics or another class's methods as parameter to narrow an accepted classes.
Another primary key class should inherit it and add your specific fields as keys. For example:
public class PassportPK extends PrimaryKey {
private String number;
private String series;
public PassportPK() {}
public PassportPK(String number, String series) {
this.number = number;
this.series = series;
}
// Getters/setters are below.
}
Then it's used in the appropriate entity like this:
#Entity
#Table(name = "T_PASSPORTS")
#IdClass(PassportPK.class)
public class Passport implements Serializable {
#Id
#Column(name = "F_NUMBER")
private String number;
#Id
#Column(name = "F_SERIES")
private String series;
public Passport() {}
// Getters/setters are below.
}
Everything works fine if I have a deal with entities like this.
But some entities in my project have a simple primary key like int, long, String, and etc.
In this case I'd like to have a generic primary key like this one:
public class SimplePK<T extends Serializable> extends PrimaryKey {
/**
* Represents a simple key field of entity (i.e. int, long, String, ...);
*/
private T id;
public SimplePK() {}
public SimplePK(T id) {
this.id = id;
}
public T getId() {
return this.id;
}
public void setId(T id) {
this.id = id;
}
}
QUESTION: How can I resolve it in annotation mapping way?
p.s. When I'm trying to resolve it like in the previous example (via #IdClass(SimplePK.class) I catch a "org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [application-context.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Property com.testprj.entity.SimplePK.id has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit target attribute (eg #OneToMany(target=) or use an explicit #Type" exception.
p.p.s. I use Hibernate with Spring framework for wiring components.
I would be grateful for any help!
I think that you can't use a generic type inside the id Class.
Used the #IdClass to indicate the Class for the Composite Primary Key, if you want to used only one attribute like primary key you have to use #Id over the declaration and remove #IdClass.
Example:
#Entity
#Table(name = "T_PASSPORTS")
public class Passport implements Serializable {
#Id
private String id; //Or int, long...
public Passport() {}
// Getters/setters are below.
}

How to work with interfaces and JPA

I should start out by saying that I am fairly new to Java EE and that I do not have a strong theoretical background in Java yet.
I'm having trouble grasping how to use JPA together with interfaces in Java. To illustrate what I find hard I created a very simple example.
If I have two simple interfaces Person and Pet:
public interface Person
{
public Pet getPet();
public void setPet(Pet pet);
}
public interface Pet
{
public String getName();
}
And an Entity PersonEntity which implements Person as well as a PetEntity which implements Pet:
#Entity
public class PersonEntity implements Person
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private PetEntity pet;
#Override
public void setPet(Pet pet)
{
/* How do i solve this? */
}
}
#Entity
public class PetEntity implements Pet
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
/* Getters and Setters omitted */
}
How do I properly handle the case in the setPet method in which I want to persist the relationships between the two entities above?
The main reason I want to use interfaces is because I want to keep dependencies between modules/layers to the public interfaces. How else do I avoid getting a dependency from e.g. my ManagedBean directly to an Entity?
If someone recommends against using interfaces on entities, then please explain what alternatives methods or patterns there are.
You can use targetEntity property in the relationship annotation.
#Entity
public class PersonEntity implements Person {
private Long id;
private Pet pet;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
#OneToOne(targetEntity = PetEntity.class)
public Pet getPet() {
return pet;
}
public void setPet(Pet pet) {
this.pet = pet;
}
}

Categories

Resources