@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;
其實是沒有用的,不寫也可以。