我有一个想要保留的旧数据库,但这会导致休眠问题。
我当前的问题是,我的POJO中有private Calendar myTradeDateTime;
字段,并且该字段映射到2列。
第一列仅包含日期信息(例如“ 2013-05-14”),第二列仅包含时间信息(例如“ 10:09:12 PM”)。现在,我想使用休眠模式仅使用1个字段访问两列。我以为我需要一些@Converter
来处理它,但是我不知道应该怎么做,也找不到关于该主题的任何信息(2栏1栏)。
所以我的问题是,如何在hibernate 5.3中将2列映射到1个字段中?
答案 0 :(得分:0)
我认为在Hibernate中无法做到这一点。我建议同时映射两列并创建一个getter和setter,如下所示(除了已经创建的那些):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
mavenCentral()
maven { url "https://maven.google.com" }
maven { url "https://storage.googleapis.com/snap-kit-build/maven" }
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.google.firebase:firebase-plugins:1.0.4'
classpath 'com.google.gms:google-services:4.0.1'
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
maven { url "https://maven.google.com" }
maven { url "https://storage.googleapis.com/snap-kit-build/maven" }
google()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
和类似的获取/设置方法:
private LocalDate tradeDate;
private LocalTime tradeTime;
PS:设置虚拟机时区的zoneoffset。可以通过编程方式获取它吗?
public Calendar getMyTradeDateTime(){
LocalDateTime dateTime = LocalDateTime.of(this.tradeDate, this.tradeTime);
Calendar c = Calendar.getInstance();
return c.setTimeInMillis(dateTime.toEpochSecond(ZoneOffset.of("-03:00"))*1000);
}
答案 1 :(得分:0)
当您使用休眠本机API和hbm.xml时,它仍然可以像这样工作:
<property name="dateMitUltimo" type="org.UTDateUltimo">
<column name="DAT_ULTIMO" />
<column name="SL_ULTIMO" />
</property>
具有这样的UserType:
public class UTDateUltimo
implements CompositeUserType {
使用休眠的JPA-API不再有效:-( 相反,您可以尝试嵌入式功能。在xml中,它看起来像:
<entity class="de.parcit.base.db.jpa.TestEmbedded" name="TestEmbedded">
<table name="TEMBED" />
<attributes>
<!-- domain="ID" type="long" -->
<id name="id" type="long">
<!-- <generated-value strategy="TABLE" /> -->
</id>
<embedded name="dateMitUltimo" />
</attributes>
</entity>
<embeddable class="de.parcit.base.db.jpa.DateJPA" access="FIELD">
<convert converter="de.parcit.base.db.jpa.DateConverter" attribute-name="date" />
<attributes>
<!-- domain="Datum_Ultimo" -->
<basic name="date">
<column name="DAT_ULTIMO" />
</basic>
<!-- domain="SL_SI" -->
<basic name="month">
<column name="SL_ULTIMO" />
</basic>
</attributes>
</embeddable>
和
public class DateConverter
implements AttributeConverter<Date, java.sql.Date> {
我没有尝试使用批注。
更新:
“嵌入”也可以与注释一起使用。 这是一个例子: Java - JPA @Basic and @Embedded annotations
答案 2 :(得分:0)
正如我在this article中所述,JPA和Hibernate将每个实体属性映射到数据库列。但是您可以使用一种小的解决方法来实现请求的映射。
您首先需要2个实体属性,它们映射2个数据库列。如果使用基于字段的访问(注释属性而不是setter),则可以跳过这些属性的getter和setter方法。然后,您可以添加第3个属性,这是您将在业务代码中使用的属性。您需要使用@Transient
对其进行注释,并根据其他2个属性计算其值。
这里是一个映射,使用该方法将时间(postedAtTime)和日期(postedAtDate)列映射到LocalDateTime postedAt
属性。
@Entity
public class Review {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String comment;
private LocalDate postedAtDate;
private LocalTime postedAtTime;
@Transient
private LocalDateTime postedAt;
public Long getId() {
return id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public LocalDateTime getPostedAt() {
if (postedAt == null) {
this.postedAt = LocalDateTime.of(this.postedAtDate, this.postedAtTime);
}
return postedAt;
}
public void setPostedAt(LocalDateTime postedAt) {
this.postedAt = postedAt;
this.postedAtDate = postedAt.toLocalDate();
this.postedAtTime = postedAt.toLocalTime();
}
}
请注意,您需要在JPQL和条件查询中使用postedAtDate
和postedAtTime
属性。但是,只要您使用Review
实体对象,就不需要了解这两个内部属性。
答案 3 :(得分:-1)
@Entity
public class Review {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String comment;
private LocalDate postedAtDate;
private LocalTime postedAtTime;
@Transient
private LocalDateTime postedAt;
public Long getId() {
return id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public LocalDateTime getPostedAt() {
if (postedAt == null) {
this.postedAt = LocalDateTime.of(this.postedAtDate, this.postedAtTime);
}
return postedAt;
}
public void setPostedAt(LocalDateTime postedAt) {
this.postedAt = postedAt;
this.postedAtDate = postedAt.toLocalDate();
this.postedAtTime = postedAt.toLocalTime();
}
}