How to get the Prototype of Bean in Spring Boot - spring

I am using Spring Boot and Spring Data JPA. I have created one entity as a Spring bean with prototype scope. How to I get the bean for each object to persist in database?
#Entity
#Table(name="sample")
#Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Sample {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
If I don't use the entity as Spring bean then I will use the following code to get the object:
Sample sample = new Sample();
How should I use the object using the Prototype scope bean in Spring Boot?

You dont want to define scope for entity. Entities are not like spring bean.
Spring data uses three important components for persisting into the database.
1) Entity Class - Each table has to be defined its own java object model called entity class.
#Entity
#Table(name="sample")
public class Sample {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column(name="name") //Column name from the table
private String name;
2) Repo Interface- In Which you can define own implementation of SQL, and it would have save method by default.
public interface SampleRepo extends CrudRepository<Sample,Long>{
List<Sample> findByName(String name);
}
3) Client program:
private SampleRepo s;
//instantiate s using autowired setter/constructor
....
//Select example
List<Sample> sampleList=s.findByName("example");
//Insert example
//Id is auto. So no need to setup explicit value for it.
Sample entity=new Sample();
s.setName("Example");
s.save(entity);

Related

JPA findTopBy cannot work on spring boot 2.6.3

I am studying spring-boot and JPA. the spring-boot version is 2.6.3, which is the latest current version.
I defined my entity class like:
#Entity
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int age;
private String name;
private String genre;
// ignore the getters, setters and toString()
And defined with one projection DTO interface.
public interface AuthorDto {
public String getName();
public int getAge();
}
then defined the repository as follows:
#Repository
public interface AuthorRepository extends JpaRepository<Author, Long> {
Author findFirstByGenre(String genre);
AuthorDto findTopByGenre(String genre);
}
the method findFirstByXXX worked well, but the second method, AuthorDto findTopByGenre(String genre);, could not work well, and was ended up with the following error in the log:
Reason: Failed to create query for method public abstract com.bookstore.dto.AuthorDto com.bookstore.repository.AuthorRepository.findTopByGenre(java.lang.String)! Cannot invoke "java.lang.Class.isInterface()" because "typeToRead" is null; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract com.bookstore.dto.AuthorDto com.bookstore.repository.AuthorRepository.findTopByGenre(java.lang.String)! Cannot invoke "java.lang.Class.isInterface()" because "typeToRead" is null
I tested the same code on spring-boot 2.1.4.RELEASE, it could work well.
I tried to find any official documents on this, but didn't find useful thread on this.

Why are nested objects retrieved from a OpenFeign request to a Spring Data Rest endpoint null?

I have the following domain classes in my client app:
#Value
public class Car {
private Long id;
private Model model;
}
#Value
public class Make {
private Long id;
private String name;
private Model model;
}
#Value
public class Model {
private Long id;
private String name;
}
My client app tries to get this data from a Spring Data Rest endpoint that return a HATEOAS response. The client does this via OpenFeign:
#FeignClient(name="car-service")
#Validated
public interface CarClient {
#GetMapping("/api/cars")
CollectionModel<Car> getAllCars();
}
But the each car has its make=null. How can I get make and model to be returned?

How can I add a tenant condition to Spring Data JPA Default and Dervied Queries

I have a Springboot Application with Repositories having Spring Data JPA Queries like findOne, findAll and also derived ones like findByID or findByName etc.
What I want to achieve is multitenancy. All entities have an "account_id" column which holds the tenant.
How do I add a filter like "account_id" to all the queries metioned above without using derived queries that contains those name slike findIdAndAccountid (which would be findone)
#Repository
public interface CategoryRepository extends JpaRepository<Category, Long> {
Category findByName(String name);
}
Here's the corresponding entity
#Entity
#Table(name = "unit")
#Data
public class Unit {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
#Column(name = "account_id")
private Long account_id;
}
I know most people use schemas as tenant separation but that's impossible for me. Is there a way (I didn't find one) to add such a tenant filter condition on those queries without writing NamedQueries or using DerivedQueries. An elegeant solution like annotate the repository or entity or maybe the queries that all queries should add the additional filter "account_id"?
You can add Where clause on your Entity classes (Didnt had time to test )
#Entity
#Table(name = "unit")
#Data
#Where(clause = "account_id= :account_id")
public class Unit {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
#Column(name = "account_id")
private Long account_id;
}
Update and Solution
1. Create a Filter & FilterDef on the entity like so
#FilterDef(name="accountFilter", parameters=#ParamDef( name="accountId", type="long" ) )
#Filters( {
#Filter(name="accountFilter", condition=":accountId = account_id")
} )
public class Category {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
#Column(name = "account_id")
private Long account_id;
}
enable filtering in the controller by autowiring entitymanager, writing a method to enable the filter and activate the filter in #ModelAttribute for each request
#RestController
#RequestMapping(path = "/categories",produces = MediaType.APPLICATION_JSON_VALUE )
public class CategoryController {
private final CategoryRepository repository;
#Autowired
private EntityManager entityManager;
CategoryController(CategoryRepository repository) {
this.repository = repository;
}
private void activateFilter() {
Session session = entityManager.unwrap(Session.class);
Filter filter = session.enableFilter("accountFilter");
filter.setParameter("accountId", Long.valueOf(TenantContext.getCurrentTenant()));
}
#ModelAttribute
public void initFilter() {
activateFilter();
}
... your rest methods here
}

Spring Data JPA auditing not working

Folks,
We have really hard time in integrating auditing support in Spring DATA JPA.
We are using spring 3.2.11 and hibernate 4.3.0. (We don't want to use ORM.xml)
Problem is we are not receiving any event in the 'AuditAwareImpl' class when customer entity is saved.
(We debugged AuditingEntityListener and found AuditHandler is getting injected properly but at later point event is not fired. We suspect some class loading issue)
CODE below.
Basically we have two business entity.
#Entity(name = "CUSTOMER")
#Table(name = "CUSTOMER_DETAILS")
#EntityListeners(AuditingEntityListener.class)
public class Customer extends AbstractAuditable<User, Long> {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
User Entity :
#Entity(name = "USER")
#Table(name = "USER_DETAILS")
public class User extends AbstractPersistable<Long>{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
We have one helper class to configure spring.
#Configuration
#EnableTransactionManagement
#EnableJpaAuditing(auditorAwareRef = "auditorAwareImpl")
#EnableJpaRepositories(basePackages = "businessclass")
public class PersistenceContext {
}
AuditAwareImpl.
#Component
public class AuditorAwareImpl implements AuditorAware<User> {
public User getCurrentAuditor() {
ApplicationContext context = ApplicationContextManager.getContext();
UserRepository repository = (UserRepository)context.getBean("userRepository");
User user = new User();
user.setName("work now");
repository.save(user);
return user;
}
}
You need to call the repository's saveAndFlush method.
The save method of org.springframework.data.jpa.repository.JpaRepository supports both save and update. If it is update, it calls em.merge (), but it does not trigger the PreUpdate event. If you want to trigger PreUpdate, you Need to call the saveAndFlush method

Returning returned model object to json String using spring data jpa with hibernate

I am using spring data jpa with hibernate
This is my dao interface
#Repository
public interface IUserDAO extends JpaRepository<User, Integer>{
User findByUsername( final String username );
}
This is my User class
Entity
#Table(name="USER")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="ID", nullable = false)
private int id;
#Column(name="USERNAME", nullable = false)
private String username;
#Column(name="NAME", nullable = false)
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This is my UserImplClass
This is my UserImplClass{
#Autowired
private IUserDAO iUserDAO;
public String findUserByUserName(String username) {
User user =iUserDAO.findByUsername(username);
Convert user to json object from framework level automatically
// i can add my one implemenation of converting user to json here ,but i want to achieve it from framework so that my code is not scattered on every service level
return "jsonStringOfUserObject"
}
Is it possible with spring data jpa with hibernate so that i do not have to write code for converting java object to json string in every service level?
I am using spring ,therefore i want to achieve it from spring .
You have two options to do what you want:
1) If you plan on returning this Object as an HTTP Response, and you use Spring MVC with Controllers you can annotate your controller method as follows:
public #ResponseBody User getUser(){
return userImplClass.findUserByUserName("yourusername");
}
2) If you want the UserImplClass itself to return a JSON String (which I do't recommend, but I leave you the decision), you can use Jackson Object Mapper to do it for you (you can inject it if you declare it as a bean on your configuration xml, or create a new instance of it, I personally prefer injecting it with #Autowired)
public String findUserByUserName(String username) {
User user =iUserDAO.findByUsername(username);
ObjectMapper mapper = new ObjectMapper(); // no need to do this if you inject via #Autowired
return mapper.writeValueAsString(user);
}

Resources