Inheritance entity and setup repository - jpa

I use spring boot 3, I have many entities who use inheritance.
#Entity
#DiscriminatorValue(Animal.DOG)
public class Dog extends Animal{
}
#Entity
#DiscriminatorValue(Animal.CAT)
public class Cat extends Animal{
}
#Entity
#Table(name = "Animal", schema = "")
#DiscriminatorColumn(name = "AnimalType", discriminatorType = DiscriminatorType.STRING)
public class Animal{
}
For the repository I have
#Repository
#Transactional(readOnly = true)
public interface AnimalRepository extends JpaRepository<Animal, Long> {
}
#Repository
#Transactional(readOnly = true)
public interface DogRepository extends JpaRepository<Dog, Long> {
}
#Repository
#Transactional(readOnly = true)
public interface CatRepository extends JpaRepository<Cat, Long> {
}
In DogRepository and CatRepository, do I need to setup something to be able to call findAll and it's return only dog or cat?

Related

JPQL query on abstract mother class accessing subclasses properties

I'm facing a problem trying to make a JPA repository on an abstract class.
What I'm willing to do is a method that filters, paginates and returnes 3 differents kind of objects in a single list. Some have shared properties (grouped in AbstractClass).
Here are my different classes :
Mother abstract class
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "te_abstract_data")
#DiscriminatorColumn(name="data_type")
public abstract class AbstractData {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "data_type")
#Enumerated(EnumType.STRING)
private DataType dataType;
}
AbstractClass
#MappedSuperclass
public class AbstractClass extends AbstractData {
#ManyToOne
#JoinColumn(name = "fk_obj_id")
private ObjEntity opbj;
}
ClassA & ClassB classes
#Entity
#DiscriminatorValue("CLASS_A")
#Table(name = "te_class_a")
#PrimaryKeyJoinColumn(name="fk_data_id")
public class ClassAEntity extends AbstractClass {
// some fields...
}
ClassC
#Entity
#DiscriminatorValue("CLASS_C")
#Table(name = "te_class_c")
#PrimaryKeyJoinColumn(name="fk_data_id")
public class ClassCEntity extends AbstractData {
// some fields...
}
And here is my repository :
#Repository
public interface DataDao extends JpaRepository<AbstractData, Integer> {
#Query(value =
"SELECT ad " +
"FROM AbstractData ad " +
"WHERE ad.obj.name = :objName " +
// some other filters on various fields
"ORDER BY ad.id ASC"
)
List<AbstractData> findFiltered(
Pageable pageable,
String objName
);
}
The current query in my repository ignores only returns ClassB object, even if ClassA and C's objects are well initialized. I have no idea about what could be wrong...
Any idea how I could solve this ?

NamedQuery with Child Class

I have a persistence model like this one :
#Entity
#Table(name="CMM_DT_EMPLOYEE")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "EMP_TYPE")
public abstract class Employee {
#Id
protected Integer employeeId;
...
}
#Entity
#DiscriminatorValue(value = "FULL")
public class FullTimeEmployee extends Employee {
protected Integer salary;
// ...`enter code here`
}
#Entity
#DiscriminatorValue(value = "PART")
public class PartTimeEmployee extends Employee {
protected Float hourlyWage;
}
Named query (select c from FullTimeEmployee c) not working. Its returning only one row although there are many rows for this discriminator type in the Employee Table. Please help.

Spring data elasticsearch - Eagerly load #Entity nested set

Given this entity:
#Entity
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "foo")
public class Foo implements Serializable {
#Column(name = "created_date", nullable = false)
private Instant createdDate;
#OneToMany(mappedBy = "foo", cascade = {CascadeType.ALL})
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Bar> bars = new HashSet<>();
}
and this repository interface:
public interface FooSearchRepository extends ElasticsearchRepository<Foo, Long> {}
How can I get the bars to be eagerly loaded when calling Iterable<T> search(QueryBuilder var1);. I thought this might work:
public interface FooSearchRepository extends ElasticsearchRepository<Foo, Long> {
#Override
#EntityGraph(attributePaths = {"bars"})
Iterable<Foo> search(QueryBuilder queryBuilder);
}
... as per here, but it doesn't appear to work as expected i.e. bars not retrieved, but createdDate is.
Any suggestions appreciated.
Thanks

How to declare a base repository for a MappedSuperclass base type with spring data?

We're having a hierarchy of entity classes where all inherit from a BaseEntity #MappedSuperclass. Is there a way to have a spring-data "base repository" that allows you to query for any BaseEntity without having to know it's type and use a specific repository?
#MappedSuperclass
public class BaseEntity {
#Id
private Long id;
private String owner;
// setter/getter etc...
}
#Entity
public class FooEntity extends BaseEntity {
private String foo;
}
#Entity
public class BarEntity extends BaseEntity {
private String bar;
}
/**
* How to declare this base repository....
*/
public interface BaseRepository extends JpaRepository<BaseEntity, ActionPK> {
List<BaseEntity> findByOwner(String owner);
}
#Component
public class MyService {
#Autowired
private BaseRepository baseRepository;
public void doSomething() {
// ... so that is can be used like this:
List<BaseEntity> entities = baseRepository.findByOwner("john");
doSomethingWith(entities);
}
}
I think the only way you could achieve this is to create a Service class that will orchestrate all the calls to your Repository classes that have an owner property. That service call would return your list of BaseEntity objects.

ebean does not generate methods for inhereted annotated fields?

This works:
#MappedSuperclass
public class ExtendableTranslation extends Model {
public String label;
}
#Entity
public class LeagueT extends ExtendableTranslation {
#Id
public Integer id;
}
but if I move id field to the superclass:
#MappedSuperclass
public class ExtendableTranslation extends Model {
public String label;
#Id
public Integer id;
}
#Entity
public class LeagueT extends ExtendableTranslation {
}
I have an error:
[RuntimeException: java.lang.NoSuchMethodError: models.translations.LeagueT._ebean_setni_id(Ljava/lang/Integer;)V]
It's the same for all other annotated fields (#ManyToOne, #OneToMany). Is it a bug or I'm doing something wrong?