休眠值分为两列。怎么映射?

时间:2018-08-14 14:37:54

标签: java hibernate mapping hibernate-5.x

我有一个想要保留的旧数据库,但这会导致休眠问题。

我当前的问题是,我的POJO中有private Calendar myTradeDateTime;字段,并且该字段映射到2列。

第一列仅包含日期信息(例如“ 2013-05-14”),第二列仅包含时间信息(例如“ 10:09:12 PM”)。现在,我想使用休眠模式仅使用1个字段访问两列。我以为我需要一些@Converter来处理它,但是我不知道应该怎么做,也找不到关于该主题的任何信息(2栏1栏)。

所以我的问题是,如何在hibernate 5.3中将2列映射到1个字段中?

4 个答案:

答案 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和条件查询中使用postedAtDatepostedAtTime属性。但是,只要您使用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();
    }
}