Kotlin:hibernate模型中的属性声明

Kotlin:hibernate模型中的属性声明,hibernate,kotlin,properties,model,notnull,Hibernate,Kotlin,Properties,Model,Notnull,我们有很多java应用程序,并且正在尝试在Kotlin中实现我们的第一个应用程序。问题是:初始化简单hibernate模型属性的最佳方法是什么 让我们以Java中的以下示例为例: @Entity @Table(name = "Session_Ids") public class SessionId() { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) protected Long id; @Co

我们有很多java应用程序,并且正在尝试在Kotlin中实现我们的第一个应用程序。问题是:初始化简单hibernate模型属性的最佳方法是什么

让我们以Java中的以下示例为例:

@Entity
@Table(name = "Session_Ids")
public class SessionId() {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @Column
    protected Long number;
}
现在让我们假设数据库中的id和数字永远不能为null。因此,在hibernate完成所有操作之后,模型的id字段和number字段中都会有一个值

在科特林我怎么能做到? 我不能用null初始化它们,因为我必须将这些字段声明为null,而它们不应该是null。我不能使用lateinit,因为这两个字段都是基本的长类型

防止将它们定义为可空的唯一方法是使用错误的默认值初始化它们。差不多

var number: Long = -1
但我觉得这是不对的

在Kotlin有没有这样的最佳实践


提前谢谢你

我使用
0
false
&c表示不可为空的字段(而
null
表示可为空的字段)-以最合理的值作为“默认”值

(我不确定这是否是最佳实践,但这是我迄今为止看到的最佳选择!)


当然,在加载现有实体时,该值将被覆盖-但在创建新实体时,它可能会用于您不手动设置的字段。因此,这可能会通知您的选择。

我遇到了与您相同的问题,我通过定义变量has nullable,然后添加注释
@Column(nullable=false)
,,这样您就知道您的实体在数据库中总是有一个id。下面是一个您可以拥有的示例:

class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    val id: Long? = null
}

我不知道这是否是最好的解决方案,但我希望它能帮助您。

我找到的另一个解决方案是kotlins数据类,但我仍然不确定这是否是一个好方法

我问题中Java类的Kotlin版本如下所示:

@Entity
@Table(name = "Session_Ids")
data class SessionId(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long?,

    @Column
    var number: Long,
){
    constructor(userId: Long): this(null, userId)
}
id仍然可以为空,因为否则hibernate可能会与具有相同id的现有实体发生冲突。唯一的另一个选项是0作为一个值,但我认为对于一个未持久化的实体来说,null比0更可扩展

我添加了二级构造函数以防止为ID传递null


您对此有何看法?

问题1是您的
@列变量编号:Long
。如果此字段不为null,则应将其移动到构造函数并在其中初始化:

课堂会话(
@纵队
变量编号:Long
) 
对于所有其他非空字段也应该这样做,它们应该在对象创建期间初始化

问题2是惰性ID,它总是不为null,但在对象创建期间是未知的,并且在插入时由Hibernate填充。这起案件在科特林似乎没有得到解决。作为一种解决方法,我使用java基类来处理引入了ID属性的实体:

@MappedSuperclass
公共类基实体{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@非空
保护长id;
}
如果您使用
javax.annotation.Nonnull
或kotlin识别的其他非null注释,此字段将在kotlin中被视为声明为非null,您将能够避免写入
无处不在

问题3是父子关系,其中应该插入两个实体,然后在一个关系中相互设置,我们希望在两个表中都存储相关的ID,以便查询。这在java中是可能的,但在kotlin中是不可能的,因为它需要在一侧声明一个字段为空,并强制使用
无处不在,而从业务案例的角度来看,此字段不应为空。在这种情况下,我使用以下解决方法:

@实体类用户帐户(
//用户可以有多个帐户
@字段:[
NotNull
多对一
]
val用户:用户,
)
@实体类用户{
//但总有一个主要原因
@字段:[
一对一
JoinColumn(table=table,name=“main\u account\u id”)
]
私有var\u maincount:UserAccount?=null
覆盖var mainAccount:UserAccount
get()=\u main帐户!!
设置(值){
_主帐户=值
}
}

我考虑过这一点,但我想阻止整个过程?还有!!在代码中,当我访问这些属性时。将hibernate的nullable定义为false将无助于此:/Mmm。在尝试保存时,字段仍有空的风险;实体类的用户不清楚是否允许null。如果在尝试保存时字段仍然为null,则是因为hibernate未能在此变量中输入值,因此问题将出现在其他地方。我是说,如果hibernate工作正常,就不可能有空id,对吧?技术上是的。但是您仍然必须执行所有空检查操作。例如,即使id在技术上不能为null,也不能执行var test:Long=myBaseEntity.id之类的操作。我想实现的是你可以做到这一点。我上面可能的解决方案应该可以解决除ID之外的所有属性的问题。我仍在寻找更好的ID问题解决方案:D@Materno,当然,我明白你的问题是什么,我刚刚回答了gidds的问题我想你唯一的解决办法是用默认值初始化变量,但是如果你找到更好的方法来避免这个问题,请发布一个新的答案,它肯定会帮助我!我考虑过相同的默认值,但我认为这是某种隐含的知识。我喜欢它更明确,但我仍然不确定这是否可能。