How do I make my pojo classes as components, so that I can autowire wherever I want? What will be the steps to do? Is this the right way for a spring boot application?
In my application iam using lombok for getters and setters. Here is my pojo:
#Accessors(chain = true)
#NoArgsConstructor
#Getter
#Setter
#ToString
#JsonIgnoreProperties(ignoreUnknown = true)
#SuppressWarnings("all")
public class Qei implements Serializable {
private static final long serialVersionUID = 2902444063726917000L;
private Integer qeiMasterId;
private String qeiId;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = NMTCConstants.DATEFORMAT)
private Date originalDate;
private BigDecimal amount;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = NMTCConstants.DATEFORMAT)
private Date complianceEndDate;
private BigDecimal perAllocAgreementPercent;
private BigDecimal minRequiredPercent;
private Integer allocationYear;
private DealDetail dealDetail;// other class
private List<Qlici> qliciInfo;//other class
}
In order to use this class, can it be spring component?
Related
its my first time crating api in spring boot, i'm trying to create transaction api. when i'm running the application i'm getting this error
Description:
Parameter 0 of constructor in TransactionService.transactionService.modal.TransactionRequest required a bean of type 'int' that could not be found.
Action:
Consider defining a bean of type 'int' in your configuration.
Modal package:
TransactionEntity
#Getter
#Setter
#Builder
#Entity
public class TransactionEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int transactionId;
#NotNull
#Column(unique = true)
private UUID externalId;
#NotNull
private int userId;
#NotNull
private int merchantId;
#NotNull
private int clientReferenceId;
#NotNull
private double amount;
#Enumerated(EnumType.STRING)
#NotNull
private TransactionStatus status;
#NotNull
private String createdBy;
private String updatedBy;
#NotNull
private LocalDateTime createdAt;
#NotNull
private LocalDateTime updatedAt;
}
TransactionRequest
#Component
#Data
#Builder
public class TransactionRequest {
private int userId;
private int merchantId;
private int clientReferenceId;
private double amount;
private String createdBy;
}
TransactionResponse
#Component
#Data
#Builder
public class TransactionResponse {
private int userId;
private int merchantId;
private int clientReferenceId;
private double amount;
private LocalDateTime createdAt;
private TransactionStatus status;
}
TransactionDao
#Component
// Dao class
public class TransactionDao {
#Autowired
TransactionRepository transactionRepository;
TransactionEntity transactionEntity;
public TransactionResponse createTransaction(TransactionRequest transactionRequest){
LocalDateTime cuurentTime = LocalDateTime.now();
transactionEntity.builder().userId(transactionRequest.getUserId())
.merchantId(transactionRequest.getMerchantId())
.clientReferenceId(transactionRequest.getClientReferenceId())
.amount(transactionRequest.getAmount())
.createdBy(transactionRequest.getCreatedBy())
.createdAt(cuurentTime)
.updatedAt(cuurentTime)
.externalId(UUID.randomUUID())
.status(TransactionStatus.CREATED);
transactionRepository.save(transactionEntity);
return TransactionResponse.builder().status(transactionEntity.getStatus())
.createdAt(transactionEntity.getCreatedAt()).build();
}
}
TransactionService
#Service
public class TransactoinService {
#Autowired
public TransactionDao transactionDao;
public TransactionResponse createTransaction(TransactionRequest transactionRequest){
return transactionDao.createTransaction(transactionRequest);
}
}
TransactionController
#RestController
public class TransactionController {
#Autowired
TransactoinService transactoinService;
#PostMapping
TransactionResponse createTransaction(#RequestBody TransactionRequest transactionRequest){
return transactoinService.createTransaction(transactionRequest);
}
}
The TransactionRequest is annotated as #Component so spring boot autoscan will try to create a #Bean out that class.
It is also annotated with #Data so at the time of creating the bean Spring boot is trying to inject other beans as arguments into the all args constructor, and it is not finding an "int" bean to inject into the constructor.
I am guessing that the transaction response should not be a #Component or at least not a Singleton bean.
You should not create your POJO classes as a Spring Bean. Remove #Component annotation in your TransactionRequest and TransactionResponse POJO classes.
I have a super Entity class like this:
#Getter
#Setter
#NoArgsConstructor
public class GenericEntity {
#Id
private Long id;
#JsonIgnore
#CreatedBy
private Long createdBy;
#JsonIgnore
#CreatedDate
private Long createdDate;
#JsonIgnore
#LastModifiedBy
private Long updatedBy;
#JsonIgnore
#LastModifiedDate
private Long updatedDate;
#JsonIgnore
#Version
private Integer version = 0;
}
and a Role class extends from GenericEntity like this:
#Getter
#Setter
#NoArgsConstructor
public class Role extends GenericEntity {
private String name;
private String desc;
private Integer sort;
}
And after that I have interface RoleRepo like this:
#Repository
public interface RoleRepo extends ReactiveCrudRepository<Role, Long>;
In Router function, I have 2 handler methods
private Mono<ServerResponse> findAllHandler(ServerRequest request) {
return ok()
.contentType(MediaType.APPLICATION_JSON)
.body(roleRepo.findAll(), Role.class);
}
private Mono<ServerResponse> saveOrUpdateHandler(ServerRequest request) {
return ok()
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(request.bodyToMono(Role.class).flatMap(role -> {
return roleRepo.save(role);
}), Role.class);
}
The method findAllHandler works fine, but the saveOrUpdateHandler throw exception like this:
java.lang.IllegalStateException: Required identifier property not found for class org.sky.entity.system.Role!
at org.springframework.data.mapping.PersistentEntity.getRequiredIdProperty(PersistentEntity.java:105) ~[spring-data-commons-2.2.0.M2.jar:2.2.0.M2]
at org.springframework.data.r2dbc.function.convert.MappingR2dbcConverter.lambda$populateIdIfNecessary$0(MappingR2dbcConverter.java:85) ~[spring-data-r2dbc-1.0.0.M1.jar:1.0.0.M1]
But when I move
#Id
private Long id;
from GenericEntity class to Role class, the two methods work fine.
Are there any Annations #MappedSuperclass/JPA in Spring Reactive Data like that
I wish the id field in GenericEntity for all extends class
Thanks for your help
Sorry, my English so bad
I had a similar problem and after some search, I didn't find an answer to your question, so I test it by writing code and the answer is spring data R2DBC doesn't need #Mappedsuperclass. it aggregates Role class properties with Generic class properties and then inserts all into the role table without the need to use any annotation.
I have a parent class that has some shared fields and a child class that extends it.
#SuperBuilder(toBuilder = true)
#Data
public abstract class MultiTenantAuthoredDocument {
#Indexed
private String tenantId;
#CreatedDate
private LocalDateTime createdDate;
#LastModifiedDate
private LocalDateTime lastModifiedDate;
}
#Document(collection = "users")
#SuperBuilder(toBuilder = true)
#Data
#EqualsAndHashCode(callSuper = true)
#ToString(callSuper = true)
public class User extends MultiTenantAuthoredDocument {
#Id
private String id;
private String firstName;
private String lastName;
#Indexed
private String password;
#Indexed(unique = true)
private String userName;
#Indexed(unique = true)
private String email;
#Indexed
private List<UserRole> roles;
#Builder.Default
private boolean enabled = false;
}
However when running my unit tests, I get an unexpected exception when I do a findById and there's a result found namely:
No property b found on entity class be.moesmedia.erp.users.domain.User to bind constructor parameter to!
As I have no clue where property b is coming from it's pretty difficult to see what I'm doing wrong.
If anyone can help me point out what I'm doing wrong.
So I've figured out what was going wrong, Lombok generated a constructor that accepted an Object with the properties for the SuperBuilder class. Once I added #NoArgsConstructorto both the child and parent class, it works like a charm.
I am using Spring Data JPA:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.1.RELEASE</version>
</dependency>
with Spring 4.3.7.RELEASE and Hibernate 5.2.9.Final.
When I query using findAll, the List returns contains null values.
Entity:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#Entity
public class Etudiant implements Serializable {
/**
* Serial version UID
*/
private static final long serialVersionUID = -1982480763983112005L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idEtudiant")
private Integer idEtudiant;
#Column(name = "nomEtudiant")
private String nomEtudiant;
#Column(name = "prenomEtudiant")
private String prenomEtudiant;
#Column(name = "adresse")
private String adresse;
#Column(name = "dateNaissance")
private Date dateNaissance;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "etudiant_cours", joinColumns = #JoinColumn(name = "idEtudiant", referencedColumnName = "idEtudiant"), inverseJoinColumns =
#JoinColumn(name = "idCours", referencedColumnName = "idCours"))
private List<Cours> cours;
}
NB: Note that the problem is not from lombock, I had tested with getters and setters.
Repository:
#Repository
public interface EtudiantRepository extends JpaRepository<Etudiant, Integer> {
}
Service:
#Service
public class EtudiantServiceImpl {
#Autowired
EtudiantRepository etudiantRepository;
List<Etudiant> lst = new ArrayList<Etudiant>();
public List<Etudiant> getAllEtudiant() {
lst = this.etudiantRepository.findAll();
return lst;
}
}
In debug screenshot, it can be seen that etudiantRepository is null.
Maybe you are missing #EnableJpaRepositories annotation in your Configuration.
EtudiantServiceImpl is being instantiated using Dependency Injection or with the new keyword?
Finally I found the solution :
change spring version from 4.3.7.RELEASE to 4.3.10.RELEASE
you need to use context:component-scan annotation into xml configuration for scanning base package and repository package, you can find code below :
<jpa:repositories base-package="com.demo.test.repository" />
<context:component-scan annotation-config="true"
base-package="com.demo.test" />
and if findall() return null value that means table dose not having data, it is normal behavior.
and also check your datasource and entity manager connection
I am using spring boot and i want to cache some data here is my entity and repository classes
Places entity class:
#Entity
#Table(name = "PLACE_MASTER")
#Getter
#Setter
#NoArgsConstructor
#EqualsAndHashCode(callSuper = true)
#Component
public class PlaceMaster extends BaseEntity{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "PLACE_MASTER_ID")
#JsonView(View.Place.class)
private long placeMasterId;
#Column(name = "PLACE_NAME")
#JsonView(View.Place.class)
private String placeName;
#Column(name = "ALT_PLACE_NAME")
private String alternatePlaceName;
#Column(name = "PINCODE")
private String pinCode;
#Column(name="DISTRICT_NAME")
private String districtName;
#ManyToOne (cascade = CascadeType.ALL)
#JoinColumn(name = "STATE_MASTER_ID")
private StateMaster stateMaster;
}
state entity class:
#Entity
#Table(name = "STATE_MASTER")
#Getter
#Setter
#NoArgsConstructor
#EqualsAndHashCode(callSuper = true)
//#ToString
public class StateMaster extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "STATE_MASTER_ID")
private long stateMasterId;
#Column(name = "STATE_NAME")
private String stateName;
#Column(name = "STATE_CODE")
private String stateCode;
#OneToMany(mappedBy = "stateMaster", cascade = CascadeType.ALL)
private List<PlaceMaster> placeMaster = new ArrayList<PlaceMaster>();
}
public interface PlaceMasterRepository extends JpaRepository<PlaceMaster, Long> {
#Override
#Cacheable("places")
public List<PlaceMaster> findAll();
}
bootstrap application class:
#SpringBootApplication
#EnableCaching
#EnableAsync
#EnableTransactionManagement
public class myApplication {
#Autowired
private PlaceMasterRepository placeMasterRepository;
public static void main(String[] args) throws Throwable {
SpringApplication.run(GoyaanaApplication.class, args);
}
}
when i run the the spring boot application i am getting the below error. Is it due to biderectional dependency. Please help
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'entityManagerFactory': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:347)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
It is generally best to avoid circular dependencies between your bean, e.g. by moving #EnableCaching, #EnableAsync, #EnableTransactionManagement to separate #Configuration class.
In cases where it is not possible, you can get around this by adding a #Lazy annotation on the #Autowired bean. This will create a lazy proxy that will get resolved at runtime. This comes with a caveat - you can't be sure at the start of the application if it is wired up correctly.
#Lazy
#Autowired
private PlaceMasterRepository placeMasterRepository;
For details see Spring documentation.