Skip to content

Commit ddfe90e

Browse files
committed
#initial-commit
1 parent 5481cff commit ddfe90e

File tree

10 files changed

+959
-0
lines changed

10 files changed

+959
-0
lines changed

.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea
8+
*.iws
9+
*.iml
10+
*.ipr
11+
12+
### Eclipse ###
13+
.apt_generated
14+
.classpath
15+
.factorypath
16+
.project
17+
.settings
18+
.springBeans
19+
.sts4-cache
20+
21+
### NetBeans ###
22+
/nbproject/private/
23+
/nbbuild/
24+
/dist/
25+
/nbdist/
26+
/.nb-gradle/
27+
build/
28+
!**/src/main/**/build/
29+
!**/src/test/**/build/
30+
31+
### VS Code ###
32+
.vscode/
33+
34+
### Mac OS ###
35+
.DS_Store

README.md

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# Translatable for Spring Boot JPA
2+
3+
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
4+
[![Maven badge](https://maven-badges.herokuapp.com/maven-central/com.mewebstudio/spring-boot-jpa-translatable-kotlin/badge.svg?style=flat)](https://central.sonatype.com/artifact/com.mewebstudio/spring-boot-jpa-translatable-kotlin)
5+
[![javadoc](https://javadoc.io/badge2/com.mewebstudio/spring-boot-jpa-translatable-kotlin/javadoc.svg)](https://javadoc.io/doc/com.mewebstudio/spring-boot-jpa-translatable-kotlin)
6+
7+
This module provides an abstract and reusable foundation for supporting **translatable (multi-language) entities** using Spring Data JPA.
8+
It defines core interfaces, abstract repositories, and a base service class to handle translations with locale-specific logic.
9+
10+
---
11+
12+
## 📦 Package Structure
13+
14+
```
15+
com.mewebstudio.springboot.jpa.translatable
16+
├── ITranslatable.kt
17+
├── ITranslation.kt
18+
├── JpaTranslatableRepository.kt
19+
├── JpaTranslationRepository.kt
20+
└── AbstractTranslatableService.kt
21+
```
22+
23+
---
24+
25+
## 🧩 Interfaces
26+
27+
### `ITranslatable<ID, T extends ITranslation<ID, ?>>`
28+
29+
Represents an entity that supports translations.
30+
31+
```kotlin
32+
interface ITranslatable<ID, T : ITranslation<ID, *>> {
33+
val id: ID
34+
val translations: MutableList<T>
35+
}
36+
```
37+
38+
---
39+
40+
### `ITranslation<ID, T>`
41+
42+
Represents a translation of an entity in a specific locale.
43+
44+
```kotlin
45+
interface ITranslation<ID, T> {
46+
val id: ID
47+
val owner: T
48+
val locale: String
49+
}
50+
```
51+
52+
---
53+
54+
## 🗃 Repositories
55+
56+
### `JpaTranslatableRepository<T : ITranslatable<ID, TR>, ID, TR : ITranslation<ID, *>> : JpaRepository<T, ID>`
57+
58+
Generic JPA repository for translatable entities.
59+
60+
```kotlin
61+
@NoRepositoryBean
62+
interface JpaTranslatableRepository<T : ITranslatable<ID, TR>, ID, TR : ITranslation<ID, *>> : JpaRepository<T, ID> {
63+
// ...
64+
}
65+
```
66+
67+
---
68+
69+
### `JpaTranslationRepository<T, ID, OWNER>`
70+
71+
Generic JPA repository for translation entities.
72+
73+
```kotlin
74+
@NoRepositoryBean
75+
interface JpaTranslationRepository<T : ITranslation<ID, OWNER>, ID, OWNER> : JpaRepository<T, ID> {
76+
// ...
77+
}
78+
```
79+
80+
---
81+
82+
## 🧠 Abstract Service
83+
84+
### `AbstractTranslatableService<T, ID, TR>`
85+
86+
Provides a base service class for business logic operations.
87+
88+
```kotlin
89+
abstract class AbstractTranslatableService<T : ITranslatable<ID, TR>, ID, TR : ITranslation<ID, *>>(
90+
open val repository: JpaTranslatableRepository<T, ID, TR>
91+
) {
92+
// ...
93+
}
94+
```
95+
96+
### `AbstractTranslationService<T : ITranslation<ID, OWNER>, ID, OWNER>`
97+
98+
Provides a base service class for business logic operations.
99+
100+
```kotlin
101+
abstract class AbstractTranslationService<T : ITranslation<ID, OWNER>, ID, OWNER>(
102+
open val repository: JpaTranslationRepository<T, ID, OWNER>
103+
) {
104+
// ...
105+
}
106+
```
107+
108+
---
109+
110+
## 📥 Installation
111+
112+
#### for maven users
113+
Add the following dependency to your `pom.xml` file:
114+
```xml
115+
<dependency>
116+
<groupId>com.mewebstudio</groupId>
117+
<artifactId>spring-boot-jpa-translatable-kotlin</artifactId>
118+
<version>0.1.0</version>
119+
</dependency>
120+
```
121+
#### for gradle users
122+
Add the following dependency to your `build.gradle` file:
123+
```groovy
124+
implementation 'com.mewebstudio:spring-boot-jpa-translatable-kotlin:0.1.0'
125+
```
126+
127+
---
128+
129+
## 📌 Usage
130+
131+
You can extend these interfaces and abstract class to implement your own translatable entities and services:
132+
133+
### Translatable Entity Example
134+
```kotlin
135+
@Entity
136+
@Table(name = "categories")
137+
class Category(
138+
@Id
139+
val id: Long,
140+
141+
@OneToMany(mappedBy = "owner", cascade = [CascadeType.ALL], orphanRemoval = true, fetch = FetchType.LAZY)
142+
@OrderBy("locale ASC")
143+
override var translations: MutableList<CategoryTranslation> = mutableListOf(),
144+
) : ITranslatable<String, CategoryTranslation> {
145+
override fun toString(): String = "${this::class.simpleName}(id = $id)"
146+
}
147+
```
148+
149+
### Translation Entity Example
150+
```kotlin
151+
@Entity
152+
class CategoryTranslation(
153+
@Id
154+
val id: Long,
155+
156+
@ManyToOne(fetch = FetchType.LAZY)
157+
@JoinColumn(name = "category_id", nullable = false)
158+
@OnDelete(action = OnDeleteAction.CASCADE)
159+
override val owner: Category,
160+
161+
@Column(name = "locale", nullable = false)
162+
override val locale: String,
163+
164+
@Column(name = "name", nullable = false, length = 255)
165+
var name: String,
166+
167+
@Column(name = "description", columnDefinition = "text")
168+
var description: String? = null,
169+
) : ITranslation<String, Category> {
170+
override fun toString(): String =
171+
"${this::class.simpleName}(id = $id, name = $name, locale = $locale, owner = $owner)"
172+
}
173+
```
174+
175+
### Translatable Repository Example
176+
```kotlin
177+
interface CategoryRepository : JpaTranslatableRepository<Category, String, CategoryTranslation>
178+
```
179+
180+
### Translation Repository Example
181+
```kotlin
182+
interface CategoryTranslationRepository : JpaTranslationRepository<CategoryTranslation, String, Category>
183+
```
184+
185+
### Translatable Service Example
186+
```kotlin
187+
@Service
188+
class CategoryService(
189+
private val categoryRepository: CategoryRepository,
190+
private val categoryTranslationRepository: CategoryTranslationRepository
191+
) : AbstractTranslatableService<Category, String, CategoryTranslation>(categoryRepository) {
192+
private val log: Logger by logger()
193+
194+
init {
195+
log.debug("CategoryService initialized with repository: {}", repository)
196+
requireNotNull(repository) { "CategoryRepository cannot be null" }
197+
}
198+
199+
// Custom business logic methods can be added here...
200+
201+
}
202+
```
203+
204+
---
205+
206+
## 🛠 Requirements
207+
208+
- Java 17+
209+
- Kotlin 1.9.23+
210+
- Spring Boot 3.x
211+
- Spring Data JPA
212+
213+
---
214+
215+
## 🔁 Other Implementations
216+
217+
[Spring Boot JPA Translatable (Java Maven Package)](https://github.com/mewebstudio/spring-boot-jpa-translatable)
218+
219+
## 💡 Example Implementations
220+
221+
[Spring Boot JPA Translatable - Kotlin Implementation](https://github.com/mewebstudio/spring-boot-jpa-translatable-kotlin-impl)
222+
223+
[Spring Boot JPA Translatable - Java Implementation](https://github.com/mewebstudio/spring-boot-jpa-translatable-java-impl)
224+
225+
## 📃 License
226+
227+
MIT © [mewebstudio](https://github.com/mewebstudio)

0 commit comments

Comments
 (0)