Skip to content

Data Models

Elena Moshnikova edited this page Feb 2, 2023 · 30 revisions

Kotlin & JPA work together (https://www.baeldung.com/kotlin/jpa)

  1. To use JPA, the entity classes need a constructor without parameters. By default, the Kotlin classes don’t have it, and to generate them we’ll need to use the jpa-plugin
  2. Make sure to place the id attribute in last place as it is optional and auto-generate.
  3. We do not use Kotlin Data Classes as JPA entities. This is mostly because of the complex interactions between the JPA world and those default implementations provided by the Kotlin compiler for each data class. 3.1 Most JPA entities contain at least one generated value — for example, auto-generated identifiers. This means that some properties are generated only after we persist them into the database. So, the calculated equals and hashCode are different before and after persistence, as some properties used during equals and hashCode calculations are generated after persistence. 3.2 The Kotlin compiler generates the default method implementations based on all properties of a data class. When we’re using data classes for JPA entities, some of those properties might be a lazy association with the target entity. So sometimes a harmless call to toString(), equals(), or hashCode() might issue a few more queries to load the lazy associations. This may hurt the performance, especially when we don’t even need to fetch those associations
  4. Entity example: image
  5. add toString()
  6. do not add hashCode & equals
  7. use list instead of set

1. GithubUser: // users which are getting by auto job from our github project

  • id: number
  • login: string
  • name: string (maybe empty)
  • email: string
  • avatarUrl: string
  • bio: string (means description)
  • company: string
  • contributions: number (commit count)

2. Contributor: // our project contributors: developers (are getting from github repo), surdo/speech specialists which are adding in admin application

  • id: number
  • name: string
  • description: string
  • company: string
  • name_en: string
  • description_en: string
  • company_en: string
  • type [DEVELOPER, SPECIALIST,DESIGNER, QA, OTHER]
  • picture_url: string
  • github_user_id // link to GitHubUser
  • active: boolean [true, false]
  • contribution: int // how much tasks/contribution efforts were done
  • contacts // List of contacts (should get from Contact table)

3. Contact

  • id: number
  • type: [EMAIL, PHONE, TELEGRAM]
  • value: string
  • contributor_id // link to Contributor

===============================

4. Detail daily statistic

package com.epam.brn.dto.statistic data class UserDailyDetailStatisticsDto(

/** Name of series */
val seriesName: String,

/** Count of all done exercises. */
val allDoneExercises: Int,

/** Count of unique done exercises. */
val uniqueDoneExercises: Int,

/** Count of success exercise from first time */
val doneExercisesSuccessfullyFromFirstTime: Int,

/** Repeated exercises count */
val repeatedExercises: Int,

/** Count listened words in a day*/
val listenWordsCount: Int

)

Technical info about calculation.

  1. uniqueDoneExercises - count of unique records by key exerciseIds in input data.
  2. repeatedExercises- count of repetitions of done exercises. may be calculation countOfAllStudyHistoriesInADay minus doneExercisesSuccessfullyFromFirstTime
  3. listenWordsCount in one Exercise - it is actually count of resources which are linked to done exercises tasks.
  4. doneExercisesSuccessfullyFromFirstTime - count of exercises with one StudyHistory record in input data.