# Feature request: A modifier annotation for data classes to provide a non arg constructor on JVM

**URL:** <https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549>\
**Category:** Language Design\
**Created:** [March 19, 2016, 2:05pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549 "2016-03-19T14:05:12Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![llucca54](https://avatars.discourse-cdn.com/v4/letter/l/3da27b/32.png) [@llucca54](https://discuss.kotlinlang.org/u/llucca54)\
**Post date:** [March 19, 2016, 2:05pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/1 "2016-03-19T14:05:12Z")

</div>

**Problem:**

I would to build an immutable domain model, and data classes are perfect for that.  
JPA specifies that all entities should provide a non arg empty constructor for reflection.

Currently, on Kotlin data classes, there’s two ways:

1. Provide default values for all argument in constructor.
2. Provide a secondary non arg constructor, calling the primary constructor passing imaginary values.

In my opinion, the number 1 solution isn’t a good design to prevent inconsistent object state.  
The solution number two is an inelegant hack.

**The possible solution:**

I think, that a good solution would be an additional modifier annotation, **to build a data class able to reflection** , generating an empty constructor on JVM, initializing all properties with the same principle of lateinit. This will not compromise the nullability.

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [March 24, 2016, 2:35pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/2 "2016-03-24T14:35:52Z")

</div>

Looks like you’re contradicting yourself. A data class with a default no-arg constructor that does not set any initial values to any properties is anything but immutable. And there is absolutely no way to prevent inconsistent object state if we generate such a constructor.

---

<div class="post-metadata">

**Author:** ![dwallach](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dwallach/32/1657_2.png) [@dwallach](https://discuss.kotlinlang.org/u/dwallach)\
**Post date:** [March 24, 2016, 2:39pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/3 "2016-03-24T14:39:17Z")

</div>

It’s possible that the “secondary non arg constructor” can be done with Kotlin data class’s `copy` feature, which gives you new instances with changed values.

---

<div class="post-metadata">

**Author:** ![llucca54](https://avatars.discourse-cdn.com/v4/letter/l/3da27b/32.png) [@llucca54](https://discuss.kotlinlang.org/u/llucca54)\
**Post date:** [March 25, 2016, 2:10am UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/4 "2016-03-25T02:10:30Z")

</div>

You’re right!

Let me clarify my propose:

Using JPA, I can build immutable entities with data classes ( **using only val properties** ), see this:

[https://github.com/lucasjobs/koltin-jpa-dataclass/blob/master/src/main/kotlin/model/Person.kt](https://github.com/lucasjobs/koltin-jpa-dataclass/blob/master/src/main/kotlin/model/Person.kt)

This works very fine! See my entire demo on github.

Look that, **although immutable and instantiated by a secondary private non arg constructor (calling the primary, providing imaginary values), JPA** makes a magic trick and **delivers me a beautiful entity with all correct values.**

Even though, id is a val, JPA will save the correct value id on data base.

Sounds crazy but, this entity is immutable to me, is immutable to compiler, but isn’t immutable to JPA. (It’s a desired behavior.)

I’m assuming that JPA will never deliver me an entity inconsistent (i.e. with the default values provided by me), always reflecting all entity properties values to the correct ones.

My propose is:

1. A modifier annotation generates an additional non arg constructor only in bytecode .class
2. This constructor **only** can be called by reflection.
3. When this constructor is called, they instantiate an object with all properties no initialized. ( **Kotlin lateinit principle** ). JPA don’t care about this.
4. In this moment, if any property is accessed, it should throw a special exception that clearly identifies the property being accessed and the fact that it hasn’t been initialized. **Like lateinit.** _We could say that in this particular moment, the object is in limbo._
5. Who called this constructor (by reflection), either JPA or whatever, should be responsible to provide a value through reflection to every property before delivers the object. JPA already did this.

I just want to suppress the necessity of write a secondary private non arg constructor passing imaginary arguments to primary.

---

<div class="post-metadata">

**Author:** ![llucca54](https://avatars.discourse-cdn.com/v4/letter/l/3da27b/32.png) [@llucca54](https://discuss.kotlinlang.org/u/llucca54)\
**Post date:** [March 25, 2016, 2:18am UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/5 "2016-03-25T02:18:48Z")

</div>

> It’s possible that the “secondary non arg constructor” can be done with Kotlin data class’s copy feature, which gives you new instances with changed values.

I’m sorry! I don’t understand. Could you exemplify that? Thank you!

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [March 28, 2016, 12:45pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/6 "2016-03-28T12:45:33Z")

</div>

There is no possibility to enforce that a constructor can only be called by reflection. If the constructor is in the .class file, then it will be visible to Java code, and Java code will be able to call it.

---

<div class="post-metadata">

**Author:** ![llucca54](https://avatars.discourse-cdn.com/v4/letter/l/3da27b/32.png) [@llucca54](https://discuss.kotlinlang.org/u/llucca54)\
**Post date:** [March 28, 2016, 1:52pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/7 "2016-03-28T13:52:17Z")

</div>

I understand. Thank you for your reply!

---

<div class="post-metadata">

**Author:** ![llucca54](https://avatars.discourse-cdn.com/v4/letter/l/3da27b/32.png) [@llucca54](https://discuss.kotlinlang.org/u/llucca54)\
**Post date:** [March 28, 2016, 2:17pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/8 "2016-03-28T14:17:48Z")

</div>

In really, there’s one way to prevent that java code call this constructor.

**→ Just set it private.**

So, this become accessible only by reflection:

Constructor constructor = Person.class.getDeclaredConstructor(new Class[0]);  
constructor.setAccessible(true);  
Person person = constructor.newInstance(new Object[0]);

> <https://stackoverflow.com/questions/2599440/how-can-i-access-a-private-constructor-of-a-class>

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [March 28, 2016, 4:36pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/9 "2016-03-28T16:36:09Z")

</div>

Yes, I know, thanks. Such a constructor [will not work with JPA](http://openjpa.apache.org/builds/1.2.3/apache-openjpa/docs/jpa_overview_pc.html#jpa_overview_pc_no_arg), which defeats the purpose of your suggestion.

In any case, adding a language feature in order to satisfy the specific idiosyncrasies of a specific framework does not seem to be a reasonable idea.

---

<div class="post-metadata">

**Author:** ![llucca54](https://avatars.discourse-cdn.com/v4/letter/l/3da27b/32.png) [@llucca54](https://discuss.kotlinlang.org/u/llucca54)\
**Post date:** [March 28, 2016, 6:19pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/10 "2016-03-28T18:19:10Z")

</div>

I didn’t knew that JPA Specs specifies that, because I already did this on Hibernate.

But now, I discovered that [Hibernate accepts a private constructor, but it isn’t efficient](http://stackoverflow.com/questions/19503279/hibernate-no-arg-constructor-visibility) like public or protect.

Anyway, you’re right. Thanks for your attention.

---

<div class="post-metadata">

**Author:** ![stephane.dubedat](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@stephane.dubedat](https://discuss.kotlinlang.org/u/stephane.dubedat)\
**Post date:** [May 13, 2020, 3:46pm UTC](https://discuss.kotlinlang.org/t/feature-request-a-modifier-annotation-for-data-classes-to-provide-a-non-arg-constructor-on-jvm/1549/11 "2020-05-13T15:46:36Z")

</div>

I wonder if Hidden Classes API could help here [JEP 371: Hidden Classes](https://openjdk.java.net/jeps/371)
