https://github.com/mewebstudio/spring-boot-jpa-translatable
Spring Boot JPA Translatable - Maven package
https://github.com/mewebstudio/spring-boot-jpa-translatable
hibernate java jpa maven spring-boot translatable
Last synced: about 1 month ago
JSON representation
Spring Boot JPA Translatable - Maven package
- Host: GitHub
- URL: https://github.com/mewebstudio/spring-boot-jpa-translatable
- Owner: mewebstudio
- License: mit
- Created: 2025-05-07T22:03:45.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-05-07T22:51:32.000Z (about 1 year ago)
- Last Synced: 2025-05-07T23:27:04.989Z (about 1 year ago)
- Topics: hibernate, java, jpa, maven, spring-boot, translatable
- Language: Java
- Homepage:
- Size: 13.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Translatable for Spring Boot JPA
[](https://opensource.org/licenses/MIT)
[](https://central.sonatype.com/artifact/com.mewebstudio/spring-boot-jpa-translatable)
[](https://javadoc.io/doc/com.mewebstudio/spring-boot-jpa-translatable)
This module provides an abstract and reusable foundation for supporting **translatable (multi-language) entities** using Spring Data JPA.
It defines core interfaces, abstract repositories, and a base service class to handle translations with locale-specific logic.
---
## 📦 Package Structure
```
com.mewebstudio.springboot.jpa.translatable
├── ITranslatable.java
├── ITranslation.java
├── JpaTranslatableRepository.java
├── JpaTranslationRepository.java
└── AbstractTranslatableService.java
```
---
## 🧩 Interfaces
### `ITranslatable>`
Represents an entity that supports translations.
```java
public interface ITranslatable> {
ID getId();
List getTranslations();
}
```
---
### `ITranslation`
Represents a translation of an entity in a specific locale.
```java
public interface ITranslation {
ID getId();
T getOwner();
String getLocale();
}
```
---
## 🗃 Repositories
### `JpaTranslatableRepository`
Generic JPA repository for translatable entities.
```java
@NoRepositoryBean
public interface JpaTranslatableRepository, ID, TR extends ITranslation>
extends JpaRepository {
@Query("SELECT COUNT(e) > 0 FROM #{#entityName} e JOIN e.translations t WHERE e.id = :id AND t.locale = :locale")
boolean existsByIdAndLocale(ID id, String locale);
@Query("SELECT e FROM #{#entityName} e JOIN e.translations t WHERE e.id = :id AND t.locale = :locale")
T findByIdAndLocale(ID id, String locale);
@Query("SELECT DISTINCT e FROM #{#entityName} e JOIN e.translations t WHERE t.locale = :locale")
List findAllByLocale(String locale);
Page findAllByLocale(String locale, Pageable pageable);
@Query("SELECT t FROM #{#entityName} e JOIN e.translations t WHERE e.id = :id")
List findTranslationsById(ID id);
Page findTranslationsById(ID id, Pageable pageable);
@Modifying
@Query("DELETE FROM #{#entityName} e WHERE EXISTS (SELECT 1 FROM e.translations t WHERE t.locale = :locale)")
int deleteByLocale(String locale);
@Modifying
@Query("DELETE FROM #{#entityName} e WHERE e.id = :id AND EXISTS (SELECT 1 FROM e.translations t WHERE t.locale = :locale)")
int deleteByIdAndLocale(ID id, String locale);
}
```
---
### `JpaTranslationRepository`
Generic JPA repository for translation entities.
```java
@NoRepositoryBean
public interface JpaTranslationRepository, ID, OWNER>
extends JpaRepository {
@Query("SELECT CASE WHEN COUNT(t) > 0 THEN true ELSE false END FROM #{#entityName} t WHERE t.locale = :locale")
boolean existsByLocale(String locale);
@Query("SELECT CASE WHEN COUNT(t) > 0 THEN true ELSE false END FROM #{#entityName} t WHERE t.owner.id = :ownerId AND t.locale = :locale")
boolean existsByOwnerIdAndLocale(ID ownerId, String locale);
@Query("SELECT t FROM #{#entityName} t WHERE t.owner.id = :ownerId")
List findByOwnerId(ID ownerId);
Page findByOwnerId(ID ownerId, Pageable pageable);
@Query("SELECT t FROM #{#entityName} t WHERE t.owner.id = :ownerId AND t.locale = :locale")
T findByOwnerIdAndLocale(ID ownerId, String locale);
@Modifying
@Query("DELETE FROM #{#entityName} t WHERE t.locale = :locale")
int deleteByLocale(String locale);
@Modifying
@Query("DELETE FROM #{#entityName} t WHERE t.owner.id = :ownerId AND t.locale = :locale")
int deleteByOwnerIdAndLocale(ID ownerId, String locale);
}
```
---
## 🧠 Abstract Service
### `AbstractTranslatableService`
Provides a base service class for business logic operations.
```java
public abstract class AbstractTranslatableService, ID, TR extends ITranslation> {
protected final JpaTranslatableRepository repository;
public AbstractTranslatableService(JpaTranslatableRepository repository) {
this.repository = repository;
}
public boolean existsByIdAndLocale(ID id, String locale) {
return repository.existsByIdAndLocale(id, locale);
}
public T findByIdAndLocale(ID id, String locale) {
return repository.findByIdAndLocale(id, locale);
}
public List findAllByLocale(String locale) {
return repository.findAllByLocale(locale);
}
public Page findAllByLocale(String locale, Pageable pageable) {
return repository.findAllByLocale(locale, pageable);
}
public List findTranslationsById(ID id) {
return repository.findTranslationsById(id);
}
public Page findTranslationsById(ID id, Pageable pageable) {
return repository.findTranslationsById(id, pageable);
}
@Transactional
public int deleteByLocale(String locale) {
return repository.deleteByLocale(locale);
}
@Transactional
public int deleteByIdAndLocale(ID id, String locale) {
return repository.deleteByIdAndLocale(id, locale);
}
}
```
---
## 📥 Installation
#### for maven users
Add the following dependency to your `pom.xml` file:
```xml
com.mewebstudio
spring-boot-jpa-translatable
0.1.1
```
#### for gradle users
Add the following dependency to your `build.gradle` file:
```groovy
implementation 'com.mewebstudio:spring-boot-jpa-translatable:0.1.1'
```
---
## 📌 Usage
You can extend these interfaces and abstract class to implement your own translatable entities and services:
### Translatable Entity Example
```java
@Entity
public class Category implements ITranslatable {
@Id private Long id;
@OneToMany(mappedBy = "owner")
private List translations;
// getters...
}
```
### Translation Entity Example
```java
@Entity
public class CategoryTranslation implements ITranslation {
@Id private Long id;
@ManyToOne
private Category owner;
private String locale;
private String name;
// getters...
}
```
### Translatable Repository Example
```java
public interface CategoryRepository extends JpaTranslatableRepository {
// Custom query methods can be added here
}
```
### Translation Repository Example
```java
public interface CategoryTranslationRepository extends JpaTranslationRepository {
// Custom query methods can be added here
}
```
### Translatable Service Example
```java
@Service
@Slf4j
public class CategoryService extends AbstractTranslatableService {
private final CategoryRepository categoryRepository;
private final CategoryTranslationRepository categoryTranslationRepository;
/**
* Constructs a new CategoryService.
*
* @param categoryRepository the category repository
* @param categoryTranslationRepository the category translation repository
*/
public CategoryService(CategoryRepository categoryRepository, CategoryTranslationRepository categoryTranslationRepository) {
super(categoryRepository);
this.categoryRepository = categoryRepository;
this.categoryTranslationRepository = categoryTranslationRepository;
log.debug("CategoryService initialized with repository: {}", categoryRepository);
Objects.requireNonNull(categoryRepository, "CategoryRepository cannot be null");
}
// Custom business logic methods can be added here
}
```
---
## 🛠 Requirements
- Java 17+
- Spring Boot 3.x
- Spring Data JPA
---
## 🔁 Other Implementations
[Spring Boot JPA Translatable (Kotlin Maven Package)](https://github.com/mewebstudio/spring-boot-jpa-translatable-kotlin)
## 💡 Example Implementations
[Spring Boot JPA Translatable - Java Implementation](https://github.com/mewebstudio/spring-boot-jpa-translatable-java-impl)
[Spring Boot JPA Translatable - Kotlin Implementation](https://github.com/mewebstudio/spring-boot-jpa-translatable-kotlin-impl)
## 📃 License
MIT © [mewebstudio](https://github.com/mewebstudio)