Hibernate,一对一外键单向 记录。Timestamp 的一个坑。

首先是2张表

表A:

表B:

其中表B中的FormBaseId对应表A中的SubjectID. 数据库中没有设置外键关系。

下面是2个对应的实体

package questionnaire.model;

/**
 * AbstractAdsubject entity provides the base persistence definition of the
 * Adsubject entity. @author MyEclipse Persistence Tools
 */

public abstract class AbstractAdsubject implements java.io.Serializable {

    // Fields

    private Integer adSubjectId;
    //private Integer formBaseId;
    private String advertisingType;
    private String advertisingContext;
    private Subject subject;//这里去掉表B中的formBaseId字段,改用实体
    // Constructors

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    /** default constructor */
    public AbstractAdsubject() {
    }

    /** full constructor */
    public AbstractAdsubject(Subject subject,String advertisingType,
            String advertisingContext) {
        this.subject = subject;
        //this.formBaseId = formBaseId;
        this.advertisingType = advertisingType;
        this.advertisingContext = advertisingContext;

    }

    // Property accessors

    public Integer getAdSubjectId() {
        return this.adSubjectId;
    }

    public void setAdSubjectId(Integer adSubjectId) {
        this.adSubjectId = adSubjectId;
    }
/*
    public Integer getFormBaseId() {
        return this.formBaseId;
    }

    public void setFormBaseId(Integer formBaseId) {
        this.formBaseId = formBaseId;
    }
*/
    public String getAdvertisingType() {
        return this.advertisingType;
    }

    public void setAdvertisingType(String advertisingType) {
        this.advertisingType = advertisingType;
    }

    public String getAdvertisingContext() {
        return this.advertisingContext;
    }

    public void setAdvertisingContext(String advertisingContext) {
        this.advertisingContext = advertisingContext;
    }

}
package questionnaire.model;

import java.sql.Timestamp;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import questionnaire.util.TimestampAdapter;

/**
 * AbstractSubject entity provides the base persistence definition of the
 * Subject entity. @author MyEclipse Persistence Tools
 */

public abstract class AbstractSubject implements java.io.Serializable {

    // Fields

    private Integer subjectId;
    private String name;
    private Integer points;
    private Integer copies;
    private String formType;
    private String thumbnail;
    private String description;
    private Timestamp updateTime;
    private Boolean isTop;
    private Boolean isValid;
    private Integer sex;
    private Integer companyId;
    private Integer startAge;
    private Integer endAge;

    // Constructors

    /** default constructor */
    public AbstractSubject() {
    }

    /** minimal constructor */
    public AbstractSubject(String name, Integer copies, Timestamp updateTime,
            Boolean isTop, Boolean isValid) {
        this.name = name;
        this.copies = copies;
        this.updateTime = updateTime;
        this.isTop = isTop;
        this.isValid = isValid;
    }

    /** full constructor */
    public AbstractSubject(String name, Integer points, Integer copies,
            String formType, String thumbnail, String description,
            Timestamp updateTime, Boolean isTop, Boolean isValid, Integer sex,
            Integer companyId, Integer startAge, Integer endAge) {
        this.name = name;
        this.points = points;
        this.copies = copies;
        this.formType = formType;
        this.thumbnail = thumbnail;
        this.description = description;
        this.updateTime = updateTime;
        this.isTop = isTop;
        this.isValid = isValid;
        this.sex = sex;
        this.companyId = companyId;
        this.startAge = startAge;
        this.endAge = endAge;
    }

    // Property accessors

    public Integer getSubjectId() {
        return this.subjectId;
    }

    public void setSubjectId(Integer subjectId) {
        this.subjectId = subjectId;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getPoints() {
        return this.points;
    }

    public void setPoints(Integer points) {
        this.points = points;
    }

    public Integer getCopies() {
        return this.copies;
    }

    public void setCopies(Integer copies) {
        this.copies = copies;
    }

    public String getFormType() {
        return this.formType;
    }

    public void setFormType(String formType) {
        this.formType = formType;
    }

    public String getThumbnail() {
        return this.thumbnail;
    }

    public void setThumbnail(String thumbnail) {
        this.thumbnail = thumbnail;
    }

    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Timestamp getUpdateTime() {
        return this.updateTime;
    }
  //这里是为了Json的时候用Timestam类型在json的时候会序列化不出来
    @XmlJavaTypeAdapter(value=TimestampAdapter.class,type=Timestamp.class)
    public void setUpdateTime(Timestamp updateTime) {
        this.updateTime = updateTime;
    }

    public Boolean getIsTop() {
        return this.isTop;
    }

    public void setIsTop(Boolean isTop) {
        this.isTop = isTop;
    }

    public Boolean getIsValid() {
        return this.isValid;
    }

    public void setIsValid(Boolean isValid) {
        this.isValid = isValid;
    }

    public Integer getSex() {
        return this.sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public Integer getCompanyId() {
        return this.companyId;
    }

    public void setCompanyId(Integer companyId) {
        this.companyId = companyId;
    }

    public Integer getStartAge() {
        return this.startAge;
    }

    public void setStartAge(Integer startAge) {
        this.startAge = startAge;
    }

    public Integer getEndAge() {
        return this.endAge;
    }

    public void setEndAge(Integer endAge) {
        this.endAge = endAge;
    }

}

下面是为了json做转换的类

package questionnaire.util;

import java.sql.Timestamp;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class TimestampAdapter extends XmlAdapter<Date, Timestamp> {    

    public Date marshal(Timestamp v) {
        return new Date(v.getTime());
    }    

    public Timestamp unmarshal(Date v) {
        return new Timestamp(
            v.getTime());
    }
}

类 XmlAdapter<ValueType,BoundType>


java.lang.Object
  
javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>

类型参数:
BoundType - JAXB 不知道如何处理的一些类型。编写一个适配器,以便允许通过 ValueType 将此类型用作内存表示形式。
ValueType - JAXB 无需其他操作便知道如何处理的类型。
在编组或解组过程中,由 JAXB 绑定框架调用这些方法:
  • XmlAdapter.marshal(...):编组过程中,JAXB 绑定框架调用 XmlAdapter.marshal(..) 将 bound 类型修改为 value 类型,然后将 value 类型编组为 XML 表示形式。
  • XmlAdapter.unmarshal(...):解组过程中,JAXB 绑定框架首先将 XML 表示形式解组为 value 类型,然后调用 XmlAdapter.unmarshal(..) 将 value 类型修改为 bound 类型。
 

下面是xml配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="questionnaire.model.Adsubject" table="adsubject" catalog="questionnaire">
        <id name="adSubjectId" type="java.lang.Integer">
            <column name="AdSubjectID" />
            <generator class="identity" />
        </id>
       <!--  <property name="formBaseId" type="java.lang.Integer">
            <column name="FormBaseId" not-null="true">
                <comment>表头�类ID</comment>
            </column>
        </property> -->
        <property name="advertisingType" type="java.lang.String">
            <column name="AdvertisingType" length="50" not-null="true">
                <comment>广å??表类å??-å?³è??Dictionary</comment>
            </column>
        </property>
        <property name="advertisingContext" type="java.lang.String">
            <column name="AdvertisingContext" length="500" not-null="true">
                <comment>广å??表å??容</comment>
            </column>
        </property><!--FormBaseId就是我们没有写的一个数据库字段 -->
         <many-to-one name="subject" class="questionnaire.model.Subject" column="FormBaseId" cascade="all" unique="true" />
    </class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="questionnaire.model.Subject" table="subject" catalog="questionnaire">
        <id name="subjectId" type="java.lang.Integer">
            <column name="SubjectID" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="Name" length="50" not-null="true">
                <comment>��</comment>
            </column>
        </property>
        <property name="points" type="java.lang.Integer">
            <column name="Points">
                <comment>积å??</comment>
            </column>
        </property>
        <property name="copies" type="java.lang.Integer">
            <column name="Copies" not-null="true">
                <comment>�填份�</comment>
            </column>
        </property>
        <property name="formType" type="java.lang.String">
            <column name="FormType" length="50">
                <comment>1æ?¯ADï¼?2æ?¯QU</comment>
            </column>
        </property>
        <property name="thumbnail" type="java.lang.String">
            <column name="Thumbnail" length="500">
                <comment>缩��</comment>
            </column>
        </property>
        <property name="description" type="java.lang.String">
            <column name="Description" length="500">
                <comment>æ??è¿°</comment>
            </column>
        </property>
        <property name="updateTime" type="java.sql.Timestamp">
            <column name="UpdateTime" length="19" not-null="true">
                <comment>����</comment>
            </column>
        </property>
        <property name="isTop" type="java.lang.Boolean">
            <column name="IsTop" not-null="true">
                <comment>��置顶</comment>
            </column>
        </property>
        <property name="isValid" type="java.lang.Boolean">
            <column name="IsValid" not-null="true">
                <comment>æ?¯å?¦æ??æ??</comment>
            </column>
        </property>
        <property name="sex" type="java.lang.Integer">
            <column name="Sex">
                <comment>�� 1���2�女</comment>
            </column>
        </property>
        <property name="companyId" type="java.lang.Integer">
            <column name="CompanyID">
                <comment>��ID</comment>
            </column>
        </property>
        <property name="startAge" type="java.lang.Integer">
            <column name="StartAge">
                <comment>��年�</comment>
            </column>
        </property>
        <property name="endAge" type="java.lang.Integer">
            <column name="EndAge">
                <comment>ç»?æ??å¹´é¾?</comment>
            </column>
        </property>
    </class>
</hibernate-mapping>

最后是调用

@GET
        @Path("testOne2One")
        @Produces("application/json;charset=UTF-8")
        public String testOne2One()
        {
            try {
                Adsubject adsubject=new Adsubject();
                adsubject.setAdvertisingContext("test");
                adsubject.setAdvertisingType("2");
                Subject subject=new Subject();
                subject.setCompanyId(1);
                subject.setCopies(1);
                subject.setDescription("qq");
                subject.setEndAge(1);
                subject.setFormType("2");
                subject.setIsTop(true);
                subject.setIsValid(true);
                subject.setName("aa");
                subject.setPoints(2);
                subject.setSex(1);
                subject.setStartAge(2);
                subject.setThumbnail("www.baidu.com");                //看见配置里面UpdateTime的长度为19,而date取出来的时间是带有毫秒的,会抛出could not insert错误,具体错误为Incorrect datetime value: ‘‘ for column ‘UpdateTime‘ at row 1
                subject.setUpdateTime(Timestamp.valueOf(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new  java.util.Date())));
                adsubject.setSubject(subject);
                HibernateUtils.save(subject);
                HibernateUtils.save(adsubject);
                return "1";
            } catch (RuntimeException e) {
                e.printStackTrace();
                return "2";
                // TODO: handle exception
            }

        }    

hibernate输出来看,执行了3次数据操作。

Hibernate: insert into questionnaire.subject (Name, Points, Copies, FormType, Thumbnail, Description, UpdateTime, IsTop, IsValid, Sex, CompanyID, StartAge, EndAge) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into questionnaire.adsubject (AdvertisingType, AdvertisingContext, FormBaseId) values (?, ?, ?)
Hibernate: update questionnaire.subject set Name=?, Points=?, Copies=?, FormType=?, Thumbnail=?, Description=?, UpdateTime=?, IsTop=?, IsValid=?, Sex=?, CompanyID=?, StartAge=?, EndAge=? where SubjectID=?

数据库没有设置外键,表A于表B示怎么关联起来的呢。

<!--FormBaseId就是我们没有写的一个数据库字段 -->
<many-to-one name="subject" class="questionnaire.model.Subject" column="FormBaseId" cascade="all" unique="true" /> 这里只指定了表A对应的字段,表B中的SubjectId怎么与FormBaseId对应起来。

执行
HibernateUtils.save(subject);的时候
SubjectId已经返回到实体中去了。在执行
HibernateUtils.save(adsubject);的时候
adsubject里并没有FormBaseId字段,hibernate却还是直接插入了
FormBaseId,它内部是怎么对应表B中的SubjectId呢?难道是自己找主键?
				
时间: 2024-08-28 17:21:52

Hibernate,一对一外键单向 记录。Timestamp 的一个坑。的相关文章

Hibernate一对一外键单向关联

模型user,address user中有一个字段为address_id与addrees的addressid进行外键关联 user sql CREATE TABLE `NewTable` ( `userid`  int(11) NOT NULL AUTO_INCREMENT , `account`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `password`  varchar(255

Hibernate一对一外键双向关联(Annotation配置)

如上图所示:一个学生有一个学生证号,一个学生证号对应一名学生.在Hibernate中怎么用Annotation来实现呢? 学生类,主键是id:学生证的主键也是Id: Student.java package edu.xaut.hibernate; import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persisten

Hibernate,关系映射的多对一单向关联、多对一双向关联、一对一主键关联、一对一外键关联、多对多关系关联

2018-11-10  22:27:02开始写 下图内容ORM.Hibernate介绍.hibername.cfg.xml结构: 下图内容hibernate映射文件结构介绍 下图内容hibernate映射文件中主键自增规则.Hibernate实例状态(瞬时状态.持久化状态.托管状态).Hibernate初始化类获取session等方法 下图内容保存数据过程 下面内容保存数据顺序.查询数据方法 get().load()和延迟加载.删除数据 下图内容删除对象顺序.修改数据顺序 下面内容关联关系映射.

Hibernate之关联关系映射(一对一主键映射和一对一外键映射)

1:Hibernate的关联关系映射的一对一外键映射: 1.1:第一首先引包,省略 1.2:第二创建实体类: 这里使用用户信息和身份证信息的关系,用户的主键编号既可以做身份证信息的主键又可以做身份证信息的外键,这里先做外键. 创建User.java: 用户和身份证一对一的关联关系映射       private IdCart idCart; IdCart.java: 身份证和用户,一对一的关系       private User user; 1 package com.bie.bean; 2

Hibernate5.2之一对一外键关联(五)

                                                 Hibernate5.2之一对一外键关联(五) 一.简介 上篇文章中笔者介绍了Hibernate关联关系中的一对一外键关联,本篇博客将介绍一对一外键关联.其实我们回过头想一想,外键关联其实就是一对多关联关系中将多的一方简化为一个,就是我们本文所要介绍的一对一的外键关联. 二.外键关联 2.1数据库表的创建 create table people ( id varchar2(255 char) not

SSH框架之Hibernate数据库外键如何插入值的问题

SSH框架之Hibernate数据库外键如何插入值的问题 一.目标: 现有表: 其中Tea_id属于外键,如何向含有外键的表中插入对应的数据. 二.pojos部分 Course_information .java package com.pojos; import java.util.Date; public class Course_information { private Integer Course_id; private String Course_name; private Inte

删除外键限制记录

Cannot delete or update a parent row: a foreign key constraint fails (`myreview/zmax_text`, CONSTRAINT `zmax_text_ibfk_1` FOREIGN KEY (`lang`) REFERENCES `zmax_lang` (`lang`)) 以上是因为,改条记录的某个字段作为innodb的另外一个表的外链.而在删除操作时会自动检查外链.解决的办法之一是,不检查外链 SET FOREIGN

hibernate5(12)注解映射[4]一对一外键关联

在实际博客站点中,文章内容的数据量非常多,它会影响我们检索文章其他数据的时间,如查询公布时间.标题.类别的等. 这个时候,我们能够尝试将文章内容存在还有一张表中,然后建立起文章--文章内容的一对一映射 一对一关联有两种方式,一种是外键关联.还有一种是复合主键关联. 外键关联 以下我们先看一个一对一单向关联的实例 /*************关联关系维护方************/ @Table(name = "t_article") @Entity public class Artic

Hibrenate一对一外键关联

一.一对一(单向):使用外部索引将其中的一个类作为parent,相对应的一个就是子类,并且参照父 类的主键ID来生成数据库表.(比如:可以将husband中设置一个wife_id对应wife中的主键id) 1.Wife 类:生成get.set方法 @Entity//注意使用注解 public class Wife { private int id; private String name; @Id//注意使用注解 @GeneratedValue//注意使用注解 public int getId(