title: Kotlin JPA Encapsulate OneToMany
body: <p>I am using JPA with Kotlin and coming against an issue trying to encapsulate a OneToMany relationship. This is something I can easily achieve in Java but having some issues due to Kotlin only having properties and no fields in classes. </p>
  
  <p>I have an order, and an order has one to many line items. The order object has a MutableList of LineItem BUT the get method SHOULD NOT return a mutable list, or anything that the caller could potentially modify, as this breaks encapsulation. The order class should be responsible for managing collection of line items and ensuring all business rules / validations are met.</p>
  
  <p>This is the code I've come up with thus far. Basically I'm using a backing property which is the MutableList which Order class will mutate, and then there is a transient property which returns Iterable, and <code>Collections.unmodifiableList(_lineItems)</code> ensure that even if caller gets the list, and cast it to MutableList they won't be able to modify it.</p>
  
  <p>Is there a better way to enforce encapsulation and integrity. Perhaps I'm just being too defensive with my design and approach. Ideally no one should be using the getter to get and modify the list, but hey it happens.</p>
  
  <pre><code>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&lt;LineItem&gt; = ArrayList()
  
      val lineItems: Iterable&lt;LineItem&gt;
      @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
      }
  }
  </code></pre>