JPA returns empty objects - jpa

My User model
#Entity
#Table(name="users")
data class User(
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = -1,
#Column(unique=true)
val username: String) : Serializable
Two records in the database
The query is fine.
[2018-02-23T14:32:07.066+0100] [Payara 4.1] [FINE] []
[org.eclipse.persistence.session./file:/Users/youri/Downloads/payara41/glassfish/domains/domain1/applications/Kwetter-1.0-SNAPSHOT/WEB-INF/classes/_kwetter.sql]
[tid: _ThreadID=28 _ThreadName=http-thread-pool::http-listener-1(4)]
[timeMillis: 1519392727066] [levelValue: 500] [[ SELECT ID, USERNAME
FROM users]]
But it outputs two empty objects, instead of two User objects
[{},{}]
Abstract Dao where I use the Entity Manager
#Stateless
abstract class Abstract<T : Serializable> {
#PersistenceContext
private lateinit var entityManager: EntityManager
abstract fun getEntityClass(): Class<T>
open fun find(id: Long): T {
return entityManager.find(getEntityClass(), id)
}
// this returns the weird two empty objects
open fun all(): List<T> {
val builder = entityManager.criteriaBuilder
val c = builder.createQuery(getEntityClass())
c.from(getEntityClass())
val query = entityManager.createQuery(c)
return query.resultList
}
}

You should use var instead of val since Kotlin won't make a setter for val fields. JPA needs to have mutable properties (which means getters & setters).
TLDR: use var instead of val

Related

Getting "detached entity passed to persist" while trying to update entity

I'm trying to update an object. As part of the process I load the old one from the database and "transfer" its property values to a new object.
But when I try to persist the new object I get the following error:
org.hibernate.PersistentObjectException: detached entity passed to persist: some.package.domain.Exercise
My entity looks as the following
#Entity
class Exercise(
val name: String,
val description: String,
#JsonIgnore
#ManyToOne
val creator: User,
#OneToMany(fetch = EAGER)
#Fetch(SUBSELECT)
val videos: MutableList<Video> = mutableListOf(),
#Id
#GeneratedValue(strategy = SEQUENCE)
val id: Long = 0
)
My code for persisting looks as the following
#Singleton
#Transactional
class ExerciseServiceDefault(override val repository: ExerciseRepository,
private val entityManager: EntityManager) : ExerciseService {
override fun update(id: Long, exercise: Exercise): Exercise {
val existing = get(id)
val new = Exercise(exercise.name, exercise.description, existing.creator, existing.videos, existing.pictures, id)
return repository.save(new)
// return entityManager.merge(new)
}
...
If I change the above code to use entityManager.merge(new) everything works just fine. But I'd rather not have to inject the entityManager.
Any clue about how I can make the updating happen using my repository?
I've tried adding cascade = [MERGE] to my relations to no avail.

Neo4J OGM field primary id is null in Scala

This is my node entity class:
#NodeEntity
class SutStateEntity(
#Id
#GeneratedValue
#Index(unique = true)
val id: String) {
def this(sutStateIdentifier: SutStateIdentifier) = this(sutStateIdentifier.hash)
def this() = this("")
}
I am using the unique hash value of sutStateIdentifier as my id.
When I store the a SutStateEntity inside of a transaction:
val sutStateEntity = new SutStateEntity(sutStateIdentifier)
session.save(sutStateEntity)
I get the following exception:
Exception in thread "main" org.neo4j.ogm.exception.core.MappingException: `Field with primary id is null for entity ....SutStateEntity#34aa8b61`
I have read that this error occurs if I have not specified a default constructor which I did.
edit:
The following example works:
#Id
#GeneratedValue
var id: java.lang.Long = 0L
I guess, I have to change the field id to var but it still does not work if I use a String. Not even with a java.lang.String.
The assigment is wrong. This works:
#Id
#GeneratedValue
var id: java.lang.Long

Kotlin JPA Inheritance advise

What I want is to have two user types that inherit from one user super class. When I'm authenticating a user through username/password I don't care who they are at that point. However once they start making requests once logged in it will become important then.
I don't know what I should be using for the inheritance type and the repositories in kotlin for this.
#MappedSuperClass
open class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
val Id: Long = 0
val username:String = ""
val password:String = ""
}
type1
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
data class Type1(
val property1: String) : User
{
val property2: String = ""
}
type2
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
data class Type2(
val property1: String) : User
{
val property2: String = ""
}
What I'd like to have is a user repository to be able to look at user name and password, and then repositories for the other two to get the specific properties of each. I tried
#Repository
interface UserRepository: JpaRepository<User, Long> {
fun getUserByUsername(username: String)
}
and then
#Repository
interface Type1Repository: UserRepository<Type1, Long>
but it wouldn't accept the <> in the type 1 repository.
I haven't found a good resource talking about this for kotlin yet. If you know of one please pass it along. Thanks.
Like shown in here: https://ideone.com/JmqsDn you are just missing the types in your intermediate interface, ie.:
interface UserRepository<User, Long>: JpaRepository<User, Long> {
fun getUserByUsername(username: String)
}
Side note: kotlin 1.1+ is required for data classes to inherit from other classes.

Kotlin shared companion object across junit tests

I have an integration test where I start an embedded MongoDB as a companion object. I want to reuse this piece of code and I am not sure if inheritance is the way to go (if possible).
It is a Spring Boot application:
This is my test:
#RunWith(SpringRunner::class)
#SpringBootTest
class RequestRepositoryTest {
#Autowired lateinit var requestRepository: RequestRepository
companion object {
private val starter = MongodStarter.getDefaultInstance()
private var _mongod: MongodProcess? = null
private var _mongo: MongoClient? = null
#BeforeClass
#JvmStatic fun beforeTest(){
val port = 27017
val _mongodExe = starter.prepare(MongodConfigBuilder()
.version(Version.Main.DEVELOPMENT)
.net(Net("localhost", port, Network.localhostIsIPv6()))
.build())
_mongod = _mongodExe.start()
_mongo = MongoClient("localhost", port)
}
#AfterClass
#JvmStatic fun afterTest(){
_mongod?.stop()
}
}
#Test
fun store() {
val id = requestRepository.store(Request(requestId = "123"))
assertNotNull(id)
}
}
My repository class:
#Repository
class RequestRepository #Autowired constructor(val datastore: Datastore)
{
fun store(request : Request) : String =
datastore.save(request).id.toString()
}
So my question is which is the 'correct' way to go about this in Kotlin.
Update edit: As an external object the test now looks a lot cleaner and the JUnit external resource is completely reusable across test classes:
Thanks #Lovis
#RunWith(SpringRunner::class)
#SpringBootTest
class RequestRepositoryTest {
companion object {
#ClassRule
#JvmField
val mongoServer = MongoServer
}
#Autowired lateinit var requestRepository: RequestRepository
#Test
fun store() {
val id = requestRepository.store(Request(requestId = "123"))
assertNotNull( id )
assertTrue { ObjectId.isValid(id) }
}
}
You should be able to achieve what you want using jUnit's #ClassRule and ExternalResource. No Kotlin magic needed :-)
Define an object in a separate File:
object MongoServer : ExternalResource() {
#Throws(Throwable::class)
override fun before() {
// before class
}
override fun after() {
// after class
}
}
Then use it within each test:
companion object {
#ClassRule
#JvmField
val mongoServer = MongoServer
}
The ClassRule annotation does the trick here, the companion object is necessary to make it static and the #JvmField annotation is necessary to make the field public. Those are restrictions by jUnit's rule system.

How to implement interface Serializable in scala?

I have scala class like:
#Entity("users")
class User(#Required val cid: String, val isAdmin: Boolean = false, #Required val dateJoined: Date = new Date() ) {
#Id var id: ObjectId = _
#Reference
val foos = new ArrayList[Foo]
}
If it was a Java class I would simply put implements java.io.Serializable but this does not work in scala. Also is foos as declared above is private or public?
How do I use a #serializable scala object?
foos is public unless marked otherwise
scala 2.9.x also have an interface named Serializable, you may extends or mixin this. before 2.9.x the #serializable is the only choice.
You can add Serialized annotation on your Scala Class (at JPA Entity for example):
Because Serializable is a trait, you can mix it into a class, even if
your class already extends another class:
#SerialVersionUID(114L)
class Employee extends Person with Serializable ...
Se more details at this link:
https://www.safaribooksonline.com/library/view/scala-cookbook/9781449340292/ch12s08.html
An example of my Entity (JPA) class writed in scala, using Serialized properties:
import javax.persistence._
import scala.beans.BeanProperty
import java.util.Date
#SerialVersionUID(1234110L)
#Entity
#Table(name = "sport_token")
class Token() extends Serializable {
#Id
#SequenceGenerator(name="SPORT_TOKEN_SEQ",catalog="ESPORTES" , sequenceName="SPORT_TOKEN_SEQ", allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE , generator="SPORT_TOKEN_SEQ")
#BeanProperty
var id: Int = _
#BeanProperty
#Column(name="token")
var token: String = _
#BeanProperty
#Column(name="active")
var active: Int = _
}