Kotlin JPA Инкапсулируйте OneToMany

Я использую JPA с Kotlin и выступаю против проблемы, пытающейся инкапсулировать отношения OneToMany. Этого я могу легко достичь на Java, но у меня есть некоторые проблемы, связанные с тем, что Kotlin имеет только свойства и поля в классах.

У меня есть заказ, и заказ имеет одну по многим позициям. Объект order имеет MutableList из LineItem, но метод get НЕ ДОЛЖЕН возвращать измененный список или что-либо, что потенциально может изменить вызывающий, поскольку это прерывает инкапсуляцию. Класс заказа должен отвечать за управление набором позиций и обеспечение выполнения всех бизнес-правил / валидации.

Это код, который я до сих пор придумал. В основном я использую свойство backing, которое является MutableList, который будет зависеть от класса Order, и затем появляется свойство переходного процесса, которое возвращает Iterable, а Collections.unmodifiableList(_lineItems) гарантирует, что даже если вызывающий получает список и отбрасывает его в MutableList они не смогут его модифицировать.

Есть ли лучший способ обеспечить инкапсуляцию и целостность. Возможно, я просто слишком защищаю свой дизайн и подход. В идеале никто не должен использовать getter, чтобы получить и изменить список, но это происходит.

 import java.util.* import javax.persistence.* @Entity @Table(name = "order") open class Order { @Id @GeneratedValue(strategy = GenerationType.AUTO) val id: Long? = null @Column(name = "first_name") lateinit var firstName: String @Column(name = "last_name") lateinit var lastName: String @OneToMany(cascade = arrayOf(CascadeType.ALL), fetch = FetchType.LAZY, mappedBy = "order") private val _lineItems: MutableList<LineItem> = ArrayList() val lineItems: Iterable<LineItem> @Transient get() = Collections.unmodifiableList(_lineItems) protected constructor() constructor(firstName: String, lastName: String) { this.firstName = firstName this.lastName = lastName } fun addLineItem(newItem: LineItem) { // do some validation and ensure all business rules are met here this._lineItems.add(newItem) } } @Entity @Table(name = "line_item") open class LineItem { @Id @GeneratedValue(strategy = GenerationType.AUTO) val id: Long? = null @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "order_id", referencedColumnName = "id") lateinit var order: Order private set // whatever properties might be here protected constructor() constructor(order: Order) { this.order = order } }