I'm using Spring Boot to write server application.
Most of the time, I write all business logic inside services, where I use @Autowired
to access repositories and other services.
However, sometimes I want to access certain service or property from @Entity
class, which cannot use @Autowired
.
For instance, I have an entity that should be able to serialize itself to JSON. In JSON, it should have imageUrl field, which contains of image name (stored in database and as a property in the @Entity
class) and base url, which is only available in application.properties. This means that I have to use @Value
annotation inside @Entity
class, but it doesn't work that way.
So I create a service which looks like this:
@Service
public class FilesService {
private static FilesService instance;
@PostConstruct
public void init() {
FilesService.instance = this;
}
public static FilesService getInstance() {
return instance;
}
@Value("${files.path}")
String filesPath;
@Value("${files.url}")
String filesUrl;
public String saveFile(MultipartFile file) throws IOException {
if (file == null || file.isEmpty()) {
return null;
}
String filename = UUID.randomUUID().toString();
file.transferTo(new File(filesPath + filename));
return filename;
}
public String getFileUrl(String filename) {
if (filename == null || filename.length() == 0) {
return null;
}
return filesUrl + filename;
}
}
And then inside the @Entity
class I write the following code:
@JsonProperty
public String getImageUrl() {
return FilesService.getInstance().getFileUrl(imageName);
}
This works, but it doesn't look right. Moreover, I concern whether this can lead to some side effects if used with less trivial @Service
classes or @Repository
classes.
What is the correct way to use @Repository
and @Service
classes from @Entity
classes or any other non-@Component
classes (classes not managed by Spring)?
In both the app and tests it's easy to get the repository by doing: @Autowired private AccountRepository accountRepository; How can I get hold of the repository in a method in the Account class?
One key point to note is that an Entity is what gets stored in a database. A repository is what interacts with a database (there's a difference). As long as we need only simple operations (such as CRUD), we need not even write the queries for these, in case we're using JPA (Java Persistence API's).
Spring @Repository annotation is used to indicate that the class provides the mechanism for storage, retrieval, search, update and delete operation on objects.
It depends on your logic and how "important" are every entity. For example, if you had the entities User and Address you could have UserRepository and AddressRepository. But only UserService, with methods like addAddress(User user, Address address)... Save this answer.
Well, I'd say there's no correct way of using repositories and services from entities since every fiber of my being screams of wrongness but that being said , you can refer to this link for suggestions on how to do it.
In your case, I think it should allow you to populate @Value
fields within your entities, which would actually be preferable to autowiring the service.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With