What is the difference between #Entity and #Document in spring boot? - spring

Can you use both annotations on your database tables?
id, just like some clarification on there differences. thank you

#Entity is used to map a class to a relational database, it represents a database table.
#Document is used to map a class to noSQL database (specifically mongoDB), it represents a MongoDB documents.
You can use both JPA or MongoRepository if you are using both databases by creating different entities and repositories for each database.
I recommend you to have a look at spring documentation (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/)

#Document is a Spring Data Mongo annotation while #Entity is part of Java Persistence API (JPA).
You can check both documentations:
Spring Data Mongo docs
JPA docs
Where into "Example 10. Repository definitions using domain classes with annotations" there is this piece of code:
interface PersonRepository extends Repository<Person, Long> { … }
#Entity
class Person { … }
interface UserRepository extends Repository<User, Long> { … }
#Document
class User { … }
And documentation says:
PersonRepository references Person, which is annotated with the JPA #Entity annotation, so this repository clearly belongs to Spring Data JPA. UserRepository references User, which is annotated with Spring Data MongoDB’s #Document annotation.
So you can see here the difference.

Related

#Cacheable for default spring data jpa methods without overriding them

Sry, if my question isn't new but i couldn't find answer.I use Spring Data JPA and Spring Cache.
I have folowing repository
#CacheConfig(cacheNames = "Category")
#Cacheable
#Repository
public interface Repository extends CrudRepository<Category, Long> {
Category findByCategory(String Category);
}
And i want to cache default CrudRepository methods, like findAll() and etc.
It's work If i override them like this
#CacheConfig(cacheNames = "Category")
#Cacheable
#Repository
public interface Repository extends CrudRepository<Category, Long> {
Category findByCategory(String Category);
List<Category> findAll();
}
But it's not convenient override them every time for every repository.
Is there a way cache defaults spring jpa methods without override them or no such way?
Yes, we can do it. Basically, Spring uses Hibernate ORM as the implementation of JPA. Hibernate itself supports caching functionality with it and will integrate better than Spring Cache.
To enable L2 cache, add these properties to your project add the following properties.
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
and dependencies hibernate-ehcache
Once this is done, all your default methods of JPA like findOne(), findAll() will be cached.
If you add any custom methods, you can add like below:
#QueryHints({ #QueryHint(name = "org.hibernate.cacheable", value ="true") }) Category findByCategory(String Category);
To test where default methods are cached, you can use the following properties to see if SQL has been executed.
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

Spring boot JPA CrudRepository for a different oracle schema

I am working on a spring boot application,
application is working fine, reading from the DB with no issue.
//working fine on schema PRINTERS_SCHEMA
public interface PrinterRepository extends CrudRepository<PrinterInfo,String>{}
my question is how to go about adding a new Repository reading from a different oracle schema?
//need this repository to read from EMPLOYEE_ SCHEMA
public interface EmployeeRepository extends CrudRepository<EmployeeInfo,String>{}
As you are using 2 different entities, you can specify the schema on the entity class:
#Entity
#Table(name = "employee", schema = "employeeschema")
public class EmployeeInfo

Writing generic spring jpa repository for all entities

I am working on Spring Boot application.
We have Service Layer,Rest Controller and Dao as repository.
I have 20 to 30 tables in my database and I dont want to create repository for each entity and extends that to CrudRepository.
ex : User is an Entity, to perform persistance operations on User, I have to create UserRepository which extends CrudRepository.
Same with Department, Company etc...
What i want to do is, I will write a BaseRepository which gonna extend CrudRepository, base repository should accept all entities and do persistance operations.
Is there a way to that ??
Don't extend CrudRepository it's functionality is all tied to the generic type, it'd be hacky to extend it for a generic implementation. You probably just want something simple which uses the JPA entity manager directly:
import javax.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
public class GenericRepository {
#Autowired
private EntityManager entityManager;
public <T, ID> T findById(Class<T> type, ID id) {
return entityManager.find(type, id);
}
}

Spring Data MongoDB add common criteria

I'm using Spring Data MongoDB repository abstraction to access mongoDB database:
public interface CustomerRepository extends MongoRepository<Customer, String> {}
...
#Autowired
private CustomerRepository customerRepository;
List<Customer> customers = customerRepository.findAll();
this will fetch all customers from mongoDB collection.
I'd like to add criteria for all CustomerRepository methods to filter customers by{"active": true} (the actual filter is more complicated if it's matter) transparently (without changing interface).
I'm thinking about overriding some base Spring Data MongoDB classes but I'm not sure how to do it.
Thanks.

Generics and Spring Data JPARepository

This is a follow-up question based on Oliver Gierke's suggestion.
We have two tables (almost same information) but for some external reasons, cannot use a common single table. I am getting an error that the base class is not a mapped entity. Oliver Gierke has mentioned in his response that it would work only for Single Table. I am assuming that is the reason. if so, could someone explain why such limitation and how can I make the following work.
Base entity:
#MappedSuperclass
public abstract class DecisionEntity {
Inherited classes:
#Entity
#Table(name="DM_INSP_TASKING_RULES_RSLT")
public class DmInspTaskingRulesRslt extends DecisionEntity implements Serializable {
#Entity
#Table(name="DM_UW_REF_RULES_RSLT")
public class DmUwRefRulesRslt extends DecisionEntity implements Serializable {
The Repository
#Repository
public interface DecisionManagementRepository<T extends DecisionEntity> extends JpaRepository<DecisionEntity, Long> {
Have defined 'packagesToScan' and also listed all the 3 classes in persistence.xml.
I am getting the 'Non an Managed Entity' for 'DecisionEntity' class.
I tried Inheritence Type - 'TABLE_PER_CLASS
This is not supported by Spring Data JPA and Java Persistance API Specification.
Spring Data JPA Issue DATAJPA-264
Repositories: throw exception at startup if entity is a not an #Entity (e.g. for #MappedSuperclass)
Status: Investigating
Resolution: Unresolved
The JPA specifications says:
A mapped superclass, unlike an entity, is not queryable and must not be passed as an argument to
EntityManager or Query operations. Persistent relationships defined by a mapped superclass must
be unidirectional.

Resources