AlekseyPleshkov
@AlekseyPleshkov
Java/Swift developer, transhumanist, dreamer.

Как правильно оформлять код на Kotlin?

Доброго времени суток. Разрабатываю свой первый крупный проект на Kotlin&Spring и возникло несколько вопросов, связанных с оформлением кода.

1) Как избежать указания в
activeUser!!.region = region
знаков !!? Вроде проверку на null я сделал.

var activeUser: User? = null
...
if (activeUser != null) {
                activeUser!!.region = region
                usersRepository.save(activeUser)
                return "success"
            }


2) Насколько правильно проверять переменную на принадлежность к классу, а не != null?

if (favoriteSelect is Favorite)
    usersModules.favoriteRepository.delete(favoriteSelect)


3) Как правильно связать две сущности базы данных? В одну сущность добавить список из нескольких (@ManyToMany вроде как). Мне нужно в Product.productPrice поместить список ProductPrice по product_id из этой же сущности.

Сущность продукта
@Entity
@Table(name = "products")
data class Product(
        @Id @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
        var id: Int = 0,
        var title: String = "",
        var img: String = "",
        var imgsSlider: String = "",
        var specialTag: String = "",
        var information: String = "",
        var composition: String = "",
        var uses: String = "",
        var dateUses: String = "",

        var date: Date = Date(),

        @OneToOne
        @JoinColumn(name = "user_id")
        var user: User? = null,

        @OneToOne
        @JoinColumn(name = "package_type")
        var packageType: PackageType? = null,

        @OneToOne
        @JoinColumn(name = "product_price")
        var productPrice: ProductPrice? = null,

        @OneToOne
        @JoinColumn(name = "product_type")
        var productType: ProductType? = null,

        @OneToOne
        @JoinColumn(name = "region_id")
        var region: Regions? = null,

        var tags: String = "",

        @OneToOne
        @JoinColumn(name = "catalog_id")
        var catalog: Catalog? = null,

        @OneToOne
        @JoinColumn(name = "stock_type")
        var stockType: StockType? = null)


В которой есть переменная productPrice .
И сущность ProductPrice

@Entity
@Table(name = "products_price")
data class ProductPrice(
        @Id @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
        var id: Int = 0,
        var productId: Int = 0,
        var packageCount: Int = 0,
        var price: Int = 0)


4) Как правильно, в боевом режиме, запустить и настроить Spring приложение на сервере? Я запускаю через Jar файл из терминала (в автозагрузку скриптов добавил на Ubuntu Server). Но через некоторое время сайт перестает работать и выдает ошибку
Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed:


Мой build.gradle
group 'ru.test'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.0.3'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
        classpath 'mysql:mysql-connector-java:5.1.34'
    }
}

apply plugin: 'kotlin'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'test'
    version =  '0.1.0'
}

springBoot {
    mainClass = 'ru.test.Application'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    // Kotlin
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

    // Spring
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")

    // Others
    compile("org.hibernate:hibernate-validator")
    compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
    compile 'mysql:mysql-connector-java:5.1.31'
    compile 'commons-dbcp:commons-dbcp:1.4'

    // Tests
    testCompile("org.springframework:spring-test")
    testCompile("junit:junit")
    testCompile 'org.springframework.security:spring-security-test'
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

jar {
    manifest {
        attributes 'Main-Class': 'ru.test.Application'
        attributes 'Class-Path': configurations.compile.collect { "lib/" + it.getName() }.join(' ')
    }

    into('lib') {
        from configurations.compile
    }
}

task copyDependencies(type: Copy) {
    into "$libsDir/lib"
    from configurations.compile
}

build.doLast {
    tasks.copyDependencies.execute()
}


И application.properties

# Settings site
server.port=8080

# Settings for database
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.enable_lazy_load_no_trans = true


Спасибо за внимание, очень надеюсь на помощь.
  • Вопрос задан
  • 822 просмотра
Пригласить эксперта
Ответы на вопрос 1
Eisinheim
@Eisinheim
fullstack developer
1) использование знаков !! антипаттерн, ну если вы явно будете грохать приложение при npe,

if (activeUser != null) {                            //тут уже выполнена проверка, 
                activeUser.region = region      //никаких !! знаков здесь быть не должно
                usersRepository.save(activeUser)
                return "success"
            }


пользуйтесь конструкицями ?.let{ } run.. also.. apply..

activeUser?.also{ it.region = region }
activeUser?.apply{ age = 10}


2) не стоит так делать, null есть null на него и проверяйте
3) не совсем понял вопрос вы пишете "В одну сущность добавить список из нескольких"
у вас ожидает один объект? и связь таблиц один к одному
@OneToOne
        @JoinColumn(name = "product_price")
        var productPrice: ProductPrice? = null,


может ожидать лист и связь таблиц @OneToMany
@OneToMany (cascade = CascadeType.ALL)
        @JoinColumn(name = "product_price")
        var productPrice: List<ProductPrice>,

почитайте подробней
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы