JPA same table with two implementing classes - jpa

I have an entity Product which contains another entity Category.
public class Product implements Serializable {
...
private Category category;
}
However, mobile products need a special kind of category.
public class MobileProduct extends Product implements Serializable {
...
private MobileCategory mobileCategory;
}
It makes sense to make MobileCategory inherit Category because in this case you won't need two classes for products but if you want to create queries using MobileCategory attributes, JPA may not allow that. If you choose to have two classes with a inheritance relationship, you are using exactly the same table with exactly the same attributes but with two implementing classes.
Which approach should I choose?

Related

Inheritance vs composition in JPA

A legacy application persistence is based on JPA. There is an entity, People, mapped to the database table People.
Now a subset of all the rows in People needs some additional fields.
One possible solution is to use jpa inheritance and create a new entity, suppose EmployeedPeople, which extends People.
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class People {
...
#Entity(name = “EmployeedPeople”)
public class EmployeedPeople extends People {
Alternatively I can use unidirectional one to one relationship
#Entity(name = “EmployeedPeople”)
public class EmployeedPeople {
...
#OneToOne(optional = false)
private People commonPersonData;
I thought about a third way too: the new entity is based on a database view which joins People table with EmployeedData table.
This last approach is good for reading EmployeedPeople but impractical for inserting and updating because I have to work with different entities (People and EmployeedData).
Which criteria can help in choosing the strategy ?
Which are the pros and cons of each solutions ?
In internet I have already found the following guide which compares the inheritance strategies and this one on composition but my ideas are not clear yet.

Implement a GenericRepository in SpringData JPA with Hibernate?

I have more than 20 entitity classes. I just don't want to generate JPA Repository for each of them. Instead a generic repository needs to be implmented
for normal crud operations like save(), findAll(), findOne().
For ex: -
#Entity
class Student{}
#Entity
class Teacher{}
public interface GenericRepository<T,Integer> extends JpaRepository{ }
Here T should hold any type of Entity.. like Student or Teacher.

Possible to ignore #TextIndexed on fields with Spring Data MongoDB?

I have class along the lines of:
public class Person {
#TextIndexed
String name;
List<Person> contacts;
// getters and setters
...
}
The #TextIndexed allows me to search people by name. However, after I recently added a list of contacts I discovered that their names will also be added to the text index. Is there a way around this other than having a separate class - identical to Person but without the #TextIndexed annotations? Perhaps an annotation that will serialize the field but not utilize its indexes?
I am not aware of such an annotation, but one possible way to go about this would be to use polymorphism. For example, an abstract Person class that is extended by both versions (indexed and non-indexed). Then only annotate the name attribute inside the class where you want it indexed.

Make EF treat inheritance hierarchy as completely separate entities

Entity Framework 6 by default when it meets inheritance creates a special entity hierarchy with either TPH, TPT or TPC. But I would like EF to treat my classes as completely separate entities.
I have the following classes hierarchy where each class is mapped to a View in DB:
[Table("v_Item")]
class Item
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
}
[Table("v_ItemWithDescription")]
class ItemWithDescription : Item
{
public string Description { get; set; }
}
This design makes it possible to get more detailed info when needed. And it is so DRY. It is also nice to cast IQueryable:
IQueryable<ItemWithDescription> query = ...;
((IQueryable<Item>) query).Where(i => i.Name == "Foo")
But EF insists on adding discriminator column and badly distorts the queries. And there seems to be no way to make EF just forget that these classes have inheritance hierarchy!
Adding discriminator column to views and switching to TPC does not help as there appear lots of UNIONs in a query. It seems that my only option is to modify EF source code if I want to stick to my inherited approach. Are there any simpler solutions?
Thanks in advance!
If you don't map the base entity, it ignores the inheritance. So here's a trick you can do:
Create a base class for your Item class and pull all members up. Let's call it ItemBase. Do not map this class, and do not add it to your DbContext.
Then Item will be a mapped class without any properties of its own (will inherit everything from the base class). Make the rest of the classes (like ItemWithDescription) extend the ItemBase too.
This way, you'll have the code re-use, but lose the inheritance relationship between Item and its children, which depending on your case, may or may not be acceptable.

Entity Framework - Same field and column name in base and derived classes

I am using EF 4.3 and am adding Audit fields to my classes and tables. I have a service layer which is getting the credentials of the client applications by using the OperationContext, so I am passing that information to my tables through EF mappings. An example of this would be:
class A
{
string CreatedByUser { get; set; }
}
class B : A
{
}
I am using the fluent interface to provide my POCO to table mappings -- when I map the CreatedByUser column in the base and derived class, the derived class mappings do not take effect and the information is not passed to the database.
I have gotten around this by creating fields in my base class for the derived classes to use that are just pass-throughs of the audit columns but this is messy.
Try making class A abstract, I think that will give you the effect you are looking for(add the columns from class A to all class/tables that inherit it)