【问题标题】:Mandatory setter for primary key in Hibernate with hbm.xml使用 hbm.xml 在 Hibernate 中强制设置主键
【发布时间】:2012-05-07 05:47:44
【问题描述】:

是否可以通过 Hibernate XML 映射配置避免主键设置器?使用注释时,您不必声明 setter 方法。见例子。我使用的是 Hibernate 4.1.2 版。

  1. 基于 XML 的配置

    public class Entity {
        private Integer id;
    
        public Integer getId() {
            return id;
        }
    }
    
    <class name="Language" table="language">
        <id name="id" column="id">
            <generator class="native" />
        </id>
    </class>
    

    初始化Hibernate时抛出异常

    Caused by: org.hibernate.PropertyNotFoundException: Could not find a setter for property id in class net.kreuzman.eshop.core.domain.l10n.Language
        at org.hibernate.property.BasicPropertyAccessor.createSetter(BasicPropertyAccessor.java:252)
        at org.hibernate.property.BasicPropertyAccessor.getSetter(BasicPropertyAccessor.java:245)
        at org.hibernate.mapping.Property.getSetter(Property.java:325)
        at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertySetter(PojoEntityTuplizer.java:444)
        at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:182)
        at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:82)
    ... 49 more
    
  2. 基于注解的配置

    @Entity
    @Table(name="entity")
    public class Entity {
        @Id
        @Column(name="id")
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Integer id;
    
            public Integer getId() {
                 return id;
            }
    }
    

这很好用。

【问题讨论】:

  • 不,你需要一个二传手——这有什么问题?
  • @Woody 我不想为成员声明 setter,它不应该被应用程序更改。将其声明为 private 对我来说似乎不太好。
  • 我认为你需要setter,但你不能将它声明为非公开的吗? (例如protected)。这只是猜测。我不是专家。
  • @Boris Strandjev 是的,我可以将其声明为非公开,但为什么呢?它永远不会被使用。对我来说似乎很尴尬。
  • @krocan - 你错了。它将被使用,但通过反射。如果这对您来说似乎很尴尬,为什么在注释案例中声明一个没有 setter 的私有字段呢?

标签: java xml hibernate jpa hbm


【解决方案1】:

你可以将访问类型设置为字段,这将实现与将注解放在字段上相同的事情。

<class name="Language" table="language">
    <id name="id" column="id" access="field">
        <generator class="native" />
    </id>
</class>

【讨论】:

  • 谢谢,这正是我要找的!
【解决方案2】:

我认为 hibernate 通过反射 (Class.newInstance()) 创建对象,这就是它需要 no args 构造函数的原因。那样 - 我不明白如何为使用过的属性省去一个设置器。你可以将 unused 字段标记为@Transient,仅此而已。

【讨论】:

  • 是的,Hibernate 通过反射创建对象,您也可以通过反射设置私有成员,因此您不需要 setter 方法。无论如何,它在使用注释时起作用,请参阅问题。
  • Opps - 是的 - 我前段时间只用过一次。
【解决方案3】:
@GeneratedValue(strategy = GenerationType.IDENTITY)

而不是自动

【讨论】:

    猜你喜欢
    • 2015-02-22
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    相关资源
    最近更新 更多