使用hibernate / JPA

时间:2015-06-10 14:56:49

标签: java hibernate date datetime timestamp-with-timezone

我使用Hibernate 4.2和JPA以及oracle 11g作为数据库。我使用简单的java程序将Date与时区信息存储在数据库中.Below是我的表的定义

 CREATE TABLE "AW"."AW_REQUEST_DETAILS_TEST" 
   (    "ID" NUMBER, 
    "REQUEST_TYPE" VARCHAR2(20 BYTE), 
    "REQUESTOR" VARCHAR2(20 BYTE), 
    "REQUESTOR_REGION" VARCHAR2(20 BYTE), 
    "REQUESTOR_TYPE" VARCHAR2(20 BYTE), 
    "EVENT_DATETIME" TIMESTAMP (6), 
    "EVENT_TYPE_ID" NUMBER, 
    "PRINTED_MTRL" VARCHAR2(1 BYTE), 
    "IS_LOCATION_USA" VARCHAR2(1 BYTE), 
    "IS_ANALYST_ATTESTATION" VARCHAR2(1 BYTE), 
    "ANALYST_ATTESTATION" VARCHAR2(500 BYTE), 
    "ANALYST_DISCLOSURE" VARCHAR2(500 BYTE), 
    "ANALYST_DERV_POS" VARCHAR2(1 BYTE), 
    "ANALYST_POS_DETAILS" VARCHAR2(500 BYTE), 
    "LAST_MODIFIED_BY" VARCHAR2(20 BYTE), 
    "LAST_MODIFIED_DATE" TIMESTAMP (6), 
    "REQ_CREATED_BY" VARCHAR2(20 BYTE), 
    "REQ_CREATE_DATE" TIMESTAMP (6) WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, 
    "REQUEST_STATUS" VARCHAR2(50 BYTE), 
    "PROCESS_INSTANCE_ID" NUMBER, 
    "RSCH_APPRVL_FILE" BLOB, 
    "IS_APPRVL_BY_RSCH" VARCHAR2(1 BYTE), 
    "IS_APPRVL_BY_CORP" VARCHAR2(1 BYTE), 
    "CORP_APPRVL_FILE" BLOB, 
    "TASKREADY_ID" NUMBER, 
    "TASKREADY_NAME" VARCHAR2(50 BYTE), 
    "REQCOMPDISCUSSDETIALSCS" VARCHAR2(255 BYTE), 
    "REQCOMPMAYDISCUSSDETAILSCS" VARCHAR2(255 BYTE), 
    "REQCONTDISCUSSDETAILSCS" VARCHAR2(255 BYTE), 
    "REQCONTMAYDISCUSSDETAILSCS" VARCHAR2(255 BYTE)
   )

这是带有适当hibernate注释的java bean类,它包含上表的映射。

    @Entity
    @Table(name = "AW_REQUEST_DETAILS_TEST")
    public class MediaRequestDetails implements WFPayload , Serializable{
            /**
         * 
         */
        private static final long serialVersionUID = 1L;


            @Id
            @SequenceGenerator(name="REQUEST_ID_SEQ", sequenceName="REQUEST_ID_DBSEQ", allocationSize=1, initialValue = 1)
            @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "REQUEST_ID_SEQ")
            @Column(name = "ID", nullable = false)
            Long requestId;//id of the request


            @Column(name="REQUEST_TYPE", nullable = false)
            String requestType;//Type of the request Media/Non Media

            @Column(name="REQUESTOR", nullable = false)
            String requestor;//SOE ID of the requestor

            @Column(name="REQUESTOR_REGION")
            String requestorRegion;//This will be auto populated once the requestor is been added.

            @Column(name="REQUESTOR_TYPE") 
            String requestorType;//requestortype OBO,analyst or Coprorate Affairs

            @Column(name="EVENT_DATETIME")
            //@Temporal(TemporalType.TIMESTAMP)
            @org.hibernate.annotations.Type(type = "com.cira.raws.mediawf.bean.impl.UtcTimestampType")
            Date eventDate;//Date of the event // Please capture sate timezone as well

            @Column(name="EVENT_TYPE_ID")
            long eventType;//Type of the event

            @Column(name="PRINTED_MTRL")
            @Type(type="yes_no")
            boolean printedMTRL;//printed material will be produced or not

            @Column(name="IS_LOCATION_USA")
            @Type(type="yes_no")
            boolean locationIsUsa;//flag will this take place in USA or Not

            @Column(name="IS_ANALYST_ATTESTATION")
            @Type(type="yes_no")
            boolean hasAnalystAtts;

            @Column(name="ANALYST_ATTESTATION")
            String analystAtts;//AnalystAttastation

            @Column(name="ANALYST_DISCLOSURE")
            String analystDisclosure;//AnalystDisclosure

            @Column(name="ANALYST_DERV_POS")
            @Type(type="yes_no")
            boolean analystDervPos;//Information Regarding the Derivative Position(Y/N)

            @Column(name="ANALYST_POS_DETAILS")
            String analystPosdetails;//Information regarding Disclosure

            @Column(name="LAST_MODIFIED_BY") 
            String lastModifiedBy;//media request modified by name

            @Column(name="LAST_MODIFIED_DATE")
            @Temporal(TemporalType.TIMESTAMP)
            Date lastModifiedDate;//date of the media request modified

            @Column(name="REQ_CREATED_BY")
            String createdBy;//media requestor creator user SOE Id.

            @Column(name="REQ_CREATE_DATE")
            //Temporal(TemporalType.TIMESTAMP)
            @org.hibernate.annotations.Type(type = "com.cira.raws.mediawf.bean.impl.UtcTimestampType")
            Date createDate;//media requestor creator user SOE Id.

            @Column(name="REQUEST_STATUS")
            String requestStatus;//Setting the status of the Request

            @Column(name="PROCESS_INSTANCE_ID")
            Long processInstaceId;

            @Column(name="TASKREADY_ID")
            Long taskReadyId;

            @Column(name="TASKREADY_NAME")
            String taskReadyName;


            @Column(name="RSCH_APPRVL_FILE")
            @Lob
            byte[] rschApprvlFile;//Attached the approval of Research Management group

            @Column(name="CORP_APPRVL_FILE")
            @Lob
            byte[] coprApprvlFile;//Attached approval of coprorate group.

            @Column(name="IS_APPRVL_BY_CORP")
            @Type(type="yes_no")
            boolean hasApprovedByCorporate;//is request been approved by corporate

            @Column(name="IS_APPRVL_BY_RSCH")
            @Type(type="yes_no")
            boolean hasApprovedByRschMgmt;//is request been approved by rsch management

//rest of the getters and setters       

    }

我创建了自定义类型 UtcTimestampType ,将当前日期/时间信息转换为 UTC时区并将其存储在数据库中。下面是它的源代码。在下面的类我已经将 Calendar.getInstance(UTC)对象传递给 st.setTimestamp 来转换当前日期/时间在IST时区到UTC。

public class UtcTimestampTypeDescriptor extends TimestampTypeDescriptor {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public static final UtcTimestampTypeDescriptor INSTANCE = new UtcTimestampTypeDescriptor();

    private static final TimeZone UTC = TimeZone.getTimeZone("UTC");

    public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicBinder<X>( javaTypeDescriptor, this ) {
            @Override
            protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
                System.out.println("do Bind method gets called " + value);
                st.setTimestamp( index, javaTypeDescriptor.unwrap( value, Timestamp.class, options ), Calendar.getInstance(UTC) );
            }
        };
    }

    public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicExtractor<X>( javaTypeDescriptor, this ) {
            @Override
            protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
                System.out.println("do Extract method gets called ");
                return javaTypeDescriptor.wrap( rs.getTimestamp( name, Calendar.getInstance(UTC) ), options );
            }
        };
    }
}

下面是我执行的用于将数据存储在表AW_REQUEST_DETAILS_TEST中的主程序。我的下面的程序由 JVM 执行,时区为 IST

public class TestRawsConnection {

    public static void main(String args[]) throws Exception{

 EntityManager entityManager = Persistence.createEntityManagerFactory("rawsjpa").createEntityManager();


        if(entityManager!=null){
            System.out.println("************* EntityManager is obtained 1234*****************");


            Date dt=new Date();
            //Date finalDate=convertDateUTC(dt);

            entityManager.getTransaction().begin();
            MediaRequestDetails obj=new MediaRequestDetails();
            obj.setRequestor("ns52289");
            obj.setRequestorRegion("USA");
            obj.setRequestorType("OBO");
            obj.setRequestType("MediaAppr");
            obj.setEventDate(dt);
            obj.setEventType(12);
            obj.setLocationIsUsa(true);
            obj.setPrintedMTRL(false);
            obj.setLocationIsUsa(false);
            obj.setHasAnalystAtts(true);
            obj.setAnalystAtts("analystattestation");
            obj.setAnalystDisclosure("analystdisclosure");
            obj.setAnalystDervPos(true);
            obj.setAnalystPosdetails("analystposdetails");
            obj.setLastModifiedBy("jinesh");
            obj.setLastModifiedDate(dt);
            obj.setCreatedBy("jinesh123");
            obj.setCreateDate(dt);
            obj.setRequestStatus("pending");
            obj.setProcessInstaceId(1234L);
            obj.setTaskReadyId(1245L);
            obj.setTaskReadyName("JInesh");
            obj.setHasApprovedByCorporate(true);
            obj.setHasApprovedByRschMgmt(true);
            obj.setCoprApprvlFile(new String("Jinesh parikh").getBytes());
            obj.setRschApprvlFile(new String("Sejal Mehta").getBytes());

            entityManager.persist(obj);
            entityManager.getTransaction().commit();

            System.out.println("Committing the data done");

}

            //entityManager.getTransaction().commit();
            System.out.println("****************** Existed fetching the record *************************");
        }
}

以上程序绝对优秀。它根据UTC时区将日期/时间存储在(REQ_CREATE_DATE)列中,但列中存储的时区名称是 ASIA / CALCUTTA ,这是我的JVM和哪个是不正确的,我希望它应该 UTC 。我的数据库服务器位于 EST 时区。下面是我执行select查询时得到的值。

select REQ_CREATE_DATE from AW_REQUEST_DETAILS_TEST;

10-JUN-15 02.13.48.000000000 PM ASIA/CALCUTTA
10-JUN-15 02.16.41.513000000 PM ASIA/CALCUTTA

在上述情况下,日期/时间信息正确但时区信息不正确?有人知道如何解决这个问题吗?

0 个答案:

没有答案