@Transient使用心得

@Transient的作用是指定該屬性或字段不是永久的。 它用於註釋實體類,映射超類或可嵌入類的屬性或字段

它既可以寫在屬性的上面,也可以寫在屬性get方法的上面。
在實際的使用過程中,如果屬性沒有get方法。下面這種寫法是沒有問題的。數據庫表中不會有test字段。

    @Transient
    private String test;

如果有get方法,就要把@Transient註解寫到get方法上面,下面這種寫法也是沒有問題的。

    private String test;

    @Transient
    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

但是如果test屬性有get方法,你又把@Transient寫在了屬性上面,數據庫表中就會新增一個字段。

    @Transient
    private String test;

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

上面這種寫法的後果就是
這裏寫圖片描述

下面來看以類作爲屬性的@Transient使用。

    @Transient
    private MemberConfig memberConfig;

上面這種情況是不會有問題的,既不會報錯也不會產生相應字段,但是怎麼寫圖什麼呢?一般來說用@Transient是希望該屬性不會在數據表中產生字段,但又可以在程序中使用它。於是,我們決定這麼寫。

    @Transient
    private MemberConfig memberConfig;

    public MemberConfig getMemberConfig() {
        MemberConfig memberConfig = new MemberConfig(getAttr());
        return memberConfig;
    }

    public void setMemberConfig(MemberConfig memberConfig) {
        this.getAttr().putAll(memberConfig.getAttr());
    }

我們希望可以用getMemberConfig()來獲取一個MemberConfig實例(getAttr()是用來給MemberConfig對象賦值),結果報錯了。錯誤代碼:

Caused by: org.hibernate.MappingException: Could not determine type for: com.zttech.demo.cms.entity.MemberConfig, at table: t_cms_config, for columns: [org.hibernate.mapping.Column(memberConfig)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:336)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:310)
    at org.hibernate.mapping.Property.isValid(Property.java:241)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:496)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1360)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1851)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    ... 81 more

這個錯誤大概意思就是在生成字段的時候無法確定MemberConfig的類型。因爲從之前的實驗中我們可以看到當一個屬性有get方法是,如果不把@Transient註解寫到get方法上,hibernate依然會在數據表中新建一個字段。所以纔會出現這樣的錯誤。
所以用下面的寫法纔是正確的:

    private MemberConfig memberConfig;

    @Transient
    public MemberConfig getMemberConfig() {
        MemberConfig memberConfig = new MemberConfig(getAttr());
        return memberConfig;
    }

    public void setMemberConfig(MemberConfig memberConfig) {
        this.getAttr().putAll(memberConfig.getAttr());
    }

既不會報錯,也不會生成字段,還能正常使用MemberConfig。當然private MemberConfig memberConfig;其實是沒有用的,不寫也可以。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章