Create new Entity Object in Spring Boot - java

I'm hoping someone could shed some more light on my confusion with JPA entities in a Spring Boot project. I've heard that one should never call new in a Spring project. I understand that this is to allow Spring to manage all of the beans, and getting a bean can be done through injection or through the application context explicitly.
However, it's not clear to me how to get a new JPA Entity. If I have a class annotated with #Entity and a repository class that handles my data access, how do I obtain a new entity object in my service layer?
I've included #EntityScan in my application's main class so I would assume that Spring is aware of the entity. But when I try to get it through the ApplicationContext an exception is raised. This makes sense because I don't believe the #Entity annotated classes are Spring Beans, and I don't think it would be correct to also annotate it with #Component. Any clarification would be greatly appreciated.
I'm currently using the new keyword and creating the entity objects myself in the service layer. A very simple example is below:
entities/User.java
#Entity
#Table(name = "users")
public class User {
#Id
private Long id;
private String username;
// Getters & Setters ...
}
repositories/UserRepository.java
#Repository
public interface UserRepository extends CrudRepository<User, Long> {
User findByUsername(String username);
}
services/UserServiceImpl.java
#Service
public class UserServiceImpl implements UserService {
UserRepository userRepository;
#Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void createAndSaveUser(String username) {
User user = new User();
user.setUsername(username);
userRepository.save(user);
}
}
And we could assume that there was some other controller classes that would utilize the service layer.
In this example I am explicitly calling the new keyword in the service class method createAndSaveUser. Is this the correct way to do it or should I be getting some prototype bean from Spring that maps to my JPA entity?

In spring you can autowire/inject your beans, components or services. However the entity should not be autowired since these interactions are done through your repository. Your repository can be autowired.
When you want to create a new instance of your entity you are allowed to call new, because this does not need to be managed by spring. You can simply use the autowired repository to save it in the database. This also works the other way around because obviously you would need the autowired repository to retrieve your entity.
So yes, your method is correct.
I hope this makes it clearer for you, if you have any questions feel free to ask :)

Whatever you are doing is completely valid in spring. In example you have provided above I could figure out that you want your entity class object itself to store the values. Its absolutely correct.
You have to use new keyword to achieve that.
If you still wish to not create a new object for your Entity you have another option to do it through Bean/POJO/VO classes and mapping your entity object with these classes.
But Still i will tell that whatever you have done is completely fine.
Actually the object you are creating is for storing value purpose not just because you have some method is there in your class and so you are bound to create new Object to be able to call that method(As we do in normal java project).In spring that is handle by #Autowired annotation to create object.
Simple example is you will be auto-wiring your repositories in your service classes.
I hope this help.

It sounds good to me: you create your entity and then ask the repository to store it.. no problem with Spring.
have you checked this out? :
http://spring.io/guides/gs/accessing-data-jpa/
have fun

Related

Spring Boot | Using a separate file for logic

I am writing a small CRUD in Spring and Java. And I want to use a separate file for writing logic, this is very convenient for me, I did this when developing with NestJS. I have a few questions, is it correct to do this in Spring, or should I do everything inside a function in the controller. And if I write logic in a separate file, I should mark the logic class as #Component and the functions inside it as #Bean, right? I am new to Spring and as I understand it, I have to do this in order for the application to work correctly and my functions to be in the application context.
AuthLogic.java
#Component
public class AuthLogic {
#Bean
public void register() {
// code ...
}
}
AuthController.java
#RestController
public class AuthController {
#RequestMapping(value = "/register", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public void register(#Valid #RequestBody UserDTO newUser) {
// here I call the register function from AuthLogic
}
}
you can mark your logic class with #Service and use that for example you can make a AuthService and use it like
#Service
public class AuthService{
public returnType login(){
//Logic
}
}
and use this like
#RestController
public class AuthController {
AuthService authService;
#RequestMapping(value = "/register", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public void register(#Valid #RequestBody UserDTO newUser) {
authService.login();
}
}
You can write your business logic in a new separate file at service layer.
Suppose you name it as AuthService and you mark it with annotation #Service.
#Service
public class AuthService{
}
You can then Autowire it in your controller class.
#RestController
public class AuthController {
#Autowired
AuthService authService;
#RequestMapping(value = "/register", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public void register(#Valid #RequestBody UserDTO newUser) {
// here I call the register function from AuthLogic
}
}
Using separate files, or classes more importantly, is very recommended in Spring, and I assume most other languages.
The #Bean annotation on AuthLogic.java is unneeded and I think may cause startup or compilation errors.
I would change the name of AuthLogic to AuthLogicImpl, create an interface named AuthLogic with the method signature void register(), and have AuthLogicImpl implement AuthLogic. Then you can create a constructor for AuthController which accepts and AuthLogic parameter and sets it to a private field (note using the interface not the implementation in the constructor).
At the core of Spring is the IoC container. This container holds "beans" that can be injected or autowired into other beans. These beans are an instance of their class and can be used by other beans. Remember Spring uses the singleton pattern, so your beans should be stateless. This allows Spring to handle the application startup for you, so you don't need to write a ton of code creating all the different services/classes and wiring them together, it's all automagically done for you.
There are two key annoitations that you appear to be confused about:
#Component Putting this above a class will create an instance of that class (a bean) and put it into the IoC container. Other beans can access this by accepting the original beans interface in its constructor. So if I put #Component above my class FooImpl which implements Foo, then I can create a class, BarImpl with the constructor public BarImpl(Foo foo) {this.foo = foo} and BarImpl can use any public method of Foo (which will use FooImpl's implementation).
#Bean this is to be put on a method of a class that is annotated with #Configuration. This tells Spring that this method should be run at startup, and this method will return a bean that Spring should add to the IoC container. This is a popular way of configuring a bean that requires some parameters, such as the bean that manages the connection to a third party service or datastore, especially when that there is a little bit of logic that needs to go into creating the bean.
Note that the above is very broad, and there are some specifics if you need to dig deep into the spring framework, so there will be more clarification in the Spring documentation or you dig into some established Spring project. However it should suffice to answer the broad question of what is going on with #Component and #Bean.
There is no specific layout or code structure for Spring Boot Projects. However, there are some best practices followed by developers that will help us too. You can divide your project into layers like service layer, entity layer, and repository layer.
We use the entity layer to write all model and POJO classes. We annotate them with #Entity.
We use #Repository to indicate that this is a repository interface that is used to do some basic CRUD operations.
Sidenote:- You don't have to write #Repository for classes that implement or interfaces that extends Repository interfaces provided by Spring Boot framework.
We use #Service to say that this is the service class where your all business logic will be present.
We use the controller layer to receive HTTP requests and send back HTTP Responses or views.
You can learn and understand more from here
You can refer to this Image to understand the structure
project structure

how to use spring annotations

I have the #Controller, #Service and #Repository classes.
The application works fine, but I think I'm not using the annotations properly for the "entity" and "repository" classes.
I'm actually not using a db(not even an in-memory db) and don't intend to.
I'm currently annotating the repository with #Repository and the entities with #Service and this is my concern: am I doing this correctly?
How should I design and use the Spring annotations to wire the entity and repository classes to the service if I don't want to persist the data?
Currently it looks like this:
Service class
#Service
public class ServiceClass{
#Autowired
RepositoryClass repositoryClass;
public ServiceClass(RepositoryClass repositoryClass) {
this.repositoryClass = repositoryClass;
}
}
Repository class
#Repository
public class RepositoryClass{
#Autowired
private Entity entity;
public DocumentRepository(Entity entity) {
this.entity = entity;
}
}
Entity class
#Service
public class Entity {
private Map<String, List<Integer>> entityMap;
public Entity (Map<String, List<Integer>> entityMap) {
this.entityMap = entityMap;
}
}
Annotating an entity class with #Service is wrong.
A class annotated with #Service is usually stateless, and for that reason, there is usually only one object of such a class.
A class annotated with #Entity is usually stateful, and for that reason, there are usually many objects of such a class.
An example scenario is a simple news service:
There is one NewsService that contains interesting code to fetch news from the repository.
For each news item, there is a NewsEntity object, holding the data of the individual news item.
The question is: what's the role of each class here. Usually a repository is the point to access data. An entity is a data object, not a logic component, so it is usually created and managed by the repository, in this example, not Spring.
It's hard to firmly say anything with only that code (no information about how every component is used), but I would remove the #Service from the Entity class. The other classes are ok with those annotations.
You can't use #Entity from data-jpa w/o setting up some db, so your entities don't need any annotation. They aren't beans that you need to wire in anywhere.
But the general idea that 'when you don't know' it's probably a service is a good one. XD
The other annotations are right.
You can basically annotate them with #Component, #Service, #Config, #Repository ... It wouldn't break your code, the names are mostly just to be more clear for the people working on the code.

Spring #Repository #Document is not necessary?

I have a spring boot application and connected to Mongo DB.
I know all most all of documents or blogs said the sample code should like this:
#Repository
public interface ProductRepository extends MongoRepository<Product, String> {
}
#Document
public class Product {
private String id;
private String name;
private int price;
}
But I found even if I remove #Repository and #Document annotations. The application still can start without error. Spring still can know ProductRepository is spring bean and also can CRUD Product collection.
So does these not necessary to add #Repository and #Document? Or is there any difference add or not add?
Not necessery.
Spring can found it, because you extends the MongoRepository interface, and add Product as it type.
#Repository is useful anyway, for example if you create a custom repository.
#Document is also, if you want to specify custom property values, for example collection name..
The annotation #Repository registers a class as a Spring bean which makes it autowirable. Spring Data doesn't use annotations but provides functionality through extending reposotory classes such as JpaRepository or MongoRepository.

How do you handle objects created at runtime in conjunction with Dependency Injection frameworks?

I love dependency injection frameworks and how they allow me to request the one object everything starts with. All the wiring is made on the first request for that "master" object.
However, there are objects that should be created during runtime, e.g. based on user input. And sometimes those newly created objects should be shared among other objects created by the framework.
My current approach is to have "uninitialized" objects injected by the framework. During runtime I set up the object with setter methods as soon as possible.
What I don't like with this approach is that the setter methods are really invoked only once and should then never be touched again. This prevents me from declaring the fields as final. I don't now how to create the object not before all necessary information is available without losing all the benefits from the DI framework.
I'm new to DI. Are there any good patterns for this?
Example:
// The service is used through out the application
interface Service {
makeRequest()
}
What I want to do after user typed in credentials:
new ConcreteService(username, password)
// but now I need to inject the concrete servive manually everywhere I need it!
What I'm currently doing:
interface Service {
makeRequest()
setCredentials(username, password)
}
// service can be injected by framework, but I don't like setter methods
// that much (and they can pollute the interface)
Most of my experience with dependency injection is with C# but I believe the concept remains the same no matter what language.
What I understand from the original poster is that he's trying to "persist" information within the dependency injection container in order to retrieve the information at a later time.
The problem with this approach is that, in a multi-threaded scenario, there's the possibility that the dependency that you are using to persist information has its values overwritten by another thread. This can happen because the dependency injection container usually holds a single instance of the object which is returned to you whenever you need it. Therefore, you need to make sure that your design is thread safe.
In my experience, using the dependency injection container to maintain state is bad.
What you register in your dependency injection container are the objects that provide a "service" and that don't maintain any state.
Objects that you use to hold information are usually business objects. These business objects should just be instantiated with "new" (without the dependency injection container), populate them in the usual manner (with setters or initialization method or constructor) and just be passed on as part of the signature of the operations that your services expose.
Note: You can register your dependency as "transient" which would tell the dependency injection container to return a new instance every time you ask for the dependency. This would avoid the need to use the "new" keyword explicitly and give you more control when writing unit tests with a mocking framework.
Hope this helps!
One way you could do it would be to use a factory.
For example, say you had this class...
public class UserBean {
private int userId;
private UserService userService;
// other resources / dependency fields etc
public UserBean(int userId, UserService userService, ...other dependencies...) {
this.userService = userService;
this.userId = userId;
this.... = ...
}
// ...getter for userId maybe etc...
// Some method that uses the user's data AND the component/service you want to inject from Spring...
public void incrementHitCount() {
userService.incrementHitCount(userId);
}
}
...where "userService" is something you want that is managed by the IoC container. If you then have a component that needs to create one of these, e.g....
#Component
public class UserHitCountIncrementerThing {
public ResponseBean doThatThing(HttpServletRequest request) {
int userId = request.<get the user Id from it...>
UserBean userbean = new UserBean(userId, /* need dependencies here! */);
...do stuff...
}
}
You could just #Autowire in all of the services to this bean, or you could create a factory and just #Autowire one, for example...
#Component
public class UserBeanFactory {
#Autowired
private UserService userService
//...other #Autowired dependencies...
public UserBean createUser(int userId) {
return new UserBean(userService, ...etc..., userId);
}
}
Now just use this where you need it, e.g...
#Component
public class UserHitCountIncrementerThing {
#Autowired
private UserBeanFactory userFactory;
public ResponseBean doThatThing(HttpServletRequest request) {
int userId = request.<get the user Id from it...>
UserBean userbean = userFactory.createUser(userId);
...do stuff...
}
}
Is this what you were getting at?
Hope this helps.

Dependency injection conflict when more than one user uses the system

I made a single Java Application using Tomcat(Prod) and Jetty(Dev) + Hibernate + Spring + Spring MVC + Fremarker
I have a issue to solve, 'cause the users are reporting that only one user can do login without conflict. If a user does login and tries to create a new entity Payment, he have a successfull transaction. But when another user does login, since then, nobody can create a new Payment.
There is no exception, a POST is executed, but seems like the Controller is not able for delivery the form to services classes.
#MappedSuperclass
#Getter
#Setter
public abstract class AbstractEntity implements Persistable, Cloneable {
//code...
}
#Entity
#Getter
#Setter
public class Pagamento extends AbstractEntity{
//code...
}
#Component
#Transactional
public class PagamentoService {
//code...
}
#Controller
#RequestMapping("/payments")
public class PagamentosController {
//code...
}
Is everything okay about Annotations and CDI? What could to be happening?
A common use case for that is using attributes of controller (or service, dao, etc.) classes. All those beans are singleton beans and are shared between all requests and sessions. You should only use local variables in all those singleton beans - except of course for attributes that are common for the whole application ...
Can it be because you are using a single-connection DataSource, so once a request takes a connection then no other requests can access it until the first one releases the one-and-only database connection.

Categories

Resources