Java 当有 getter 时,Hibernate 是否总是需要一个 setter?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2676689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does Hibernate always need a setter when there is a getter?
提问by Marcus Leon
We have some Hibernate getter methods annotated with both @Column
and @Basic
.
我们有一些用@Column
和注释的 Hibernate getter 方法@Basic
。
We get an exception if we don't have the corresponding setter. Why is this?
如果我们没有相应的 setter,我们会得到一个异常。为什么是这样?
In our case we are deriving the value returned from the getter (to get stored in the DB) and the setter has no functional purpose. So we just have an empty method to get around the error condition..
在我们的例子中,我们导出从 getter 返回的值(以存储在 DB 中)并且 setter 没有功能目的。所以我们只有一个空的方法来解决错误情况..
采纳答案by Jim Hurne
As others have mentioned, if you annotate a property getter method, then Hibernate uses the setter when reading values from the database. Basically, Hibernate assumes that anything that it is writing to the database will eventually need to be read from the database. This implies that if you annotate a getter, then it needs to call a setter when reading the object from the database.
正如其他人提到的,如果您注释属性 getter 方法,则 Hibernate 在从数据库读取值时使用 setter。基本上,Hibernate 假设它写入数据库的任何内容最终都需要从数据库中读取。这意味着如果您注释一个 getter,那么它在从数据库读取对象时需要调用一个 setter。
You can make the setter private (Hibernate will use reflection to access the setter). This is great way to preserve the contract of your class while still using Hibernate for relational mapping.
您可以将 setter 设为私有(Hibernate 将使用反射来访问 setter)。这是在仍然使用 Hibernate 进行关系映射的同时保留类的契约的好方法。
If the field is derived from other properties in the class, then why are you storing it in the database? You can use the @Transient
annotation to mark the field that it shouldn't be stored in the database. You can even use the @Formula
annotation to have Hibernate derive the field for you (it does this by using the formula in the query it sends to the database).
如果该字段是从类中的其他属性派生的,那么为什么要将其存储在数据库中?您可以使用@Transient
注释来标记不应存储在数据库中的字段。您甚至可以使用@Formula
注释让 Hibernate 为您派生字段(它通过使用它发送到数据库的查询中的公式来实现)。
回答by Roman
Hibernate uses set
method to initialize the entity which you're reading from your DB.
Hibernate 使用set
方法来初始化您从数据库中读取的实体。
Maybe, if you make access modifiers of entity fields default
or protected
or public
then Hibernate will initialize fields directly without using setter (I read something about it but I'm not sure that it works). But using setter is much more preferred way.
也许,如果你让实体字段的访问修饰符default
或protected
或public
则Hibernate会初始化场的情况下直接使用setter方法(我读了一些,但我不知道它的工作原理)。但是使用 setter 是更受欢迎的方式。
回答by khmarbaise
You should annotate your classes with the @Entity(access = AccessType.FIELD)
and annotate your attributes. This should solve your problem. The setter is the best way to support refactoring. And what's the problem with having the little setter there.
你应该用@Entity(access = AccessType.FIELD)
和注释你的属性来注释你的类。这应该可以解决您的问题。setter 是支持重构的最佳方式。还有那个小二传手有什么问题。
回答by Sebastien Lorber
If you don't use setters and use private attributes, Hibernate would have to retrieve Fields by reflection and do field.setAccessible(true). I don't think Hibernate does that.
如果您不使用 setter 并使用私有属性,则 Hibernate 将不得不通过反射检索字段并执行 field.setAccessible(true)。我不认为 Hibernate 会这样做。
I don't really know if we can tell to Hibernate to do that, but as far as i remember, default config is using setters... Put a log/sysout on a set and you'll see that it uses the setter.
我真的不知道我们是否可以告诉 Hibernate 这样做,但据我所知,默认配置是使用 setter ......在一个集合上放置一个日志/系统输出,你会看到它使用了 setter。
回答by vsingh
Set access="field"
if you do not want to use setters:
设定access="field"
,如果你不想使用setter方法:
<class name="com.demo.hibernate.Country" table="country">
<id name="countryId" column="id" type="int">
<generator class="increment" />
</id>
<property name="name" column="name" access="field" type="string" />
<property name="countryCode" column="country_code" access="field" type="string" />
</class>