得到了经典的Hibernate问题:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: entry.Authority column: username (should be mapped with insert="false" update="false")
users.hbm.xml:
<class name="entry.User" table="users">
<property name="username" column="username"/>
<set name="authorities" table="authorities" lazy="false" cascade="all">
<key column="username" not-null="true"/>
<one-to-many class="entry.Authority"/>
</set>
authorities.hbm.xml:
<class name="entry.Authority" table="authorities">
<id name="id"/>
<property name="username" column="username"/>
</class>
尝试过经典解决方案:
<property name="username" column="username" insert="false" update="false"/>
GOT:
java.sql.BatchUpdateException: Field 'username' doesn't have a default value
为什么我不能在.xml中指定username
两次?
据我了解,此声明<property name="username" column="username"/>
与User
有关,<key column="username" not-null="true"/>
与Authorities
有关。那么为什么会发生冲突?如何解决?最小入侵?
编辑:
<class name="entry.User" table="users">
<id name="id">
<generator class="increment" />
</id>
<property name="username" column="username"/>
<set name="authorities" table="authorities" lazy="false" cascade="all" inverse="true">
<key column="username" not-null="true"/>
<one-to-many class="entry.Authority"/>
</set>
...
和
<class name="entry.Authority" table="authorities">
<id name="id"/>
<property name="username" column="username"/>
<property name="authority" column="authority"/>
<many-to-one name="user" class="entry.User">
<column name="username"/>
</many-to-one>
</class>
答案 0 :(得分:2)
使用users.hbm.xml <key column="username" not-null="true"/>
中的密钥定义,您已经在权限中处理列用户名。 authority.hbm.xml中的行<property name="username" column="username"/>
是多余的,即使在多对一中使用也是如此。每次加载/更新或插入权限实例通过用户时,该字段由Hibernate自动处理。如果您还在authorities.hbm.xml中定义了该字段,那么它会被设置两次 - 这就是您收到错误消息的原因。
如果由于某些特殊原因,你真的想在authorities.hbm.xml中拥有用户名,那么你必须指定insert / update = false(就像你已经做过的那样)和一个默认值来避免你的错误信息(甚至如果从未使用默认值)。例如
<property name="username" insert="false" update="false">
<column="username" default="anyValue"/>
</property>
但我只想推荐一下:
<class name="entry.Authority" table="authorities">
<id name="id"/>
<property name="authority" column="authority"/>
<many-to-one name="user" class="entry.User">
<column name="username"/>
</many-to-one>
</class>
在您发表评论后添加:
现在我在新映射中看到一个问题:<key>
元素必须引用父表的键,而事实并非如此。 Users表中的键是id,但您使用普通属性Username作为Authority中的外键。有两种方法可以解决这个问题:
1)使用户名成为用户的密钥(删除列ID并在用户中将密钥定义为
<id name="username">
<column="username"/>
</id>
(我不确定在这种情况下,在新的Authority实例中,hibernate会自动设置成员用户名还是必须手动设置。)
新:以下是完整的映射(未经测试):
<class name="entry.User" table="users">
<id name="username" type="String">
<column="username"/>
</id>
<property name="password" column="password" type="String"/>
<property name="enabled" column="enabled" type="boolean"/>
<set name="authorities" table="authorities" lazy="false" cascade="all" inverse="true">
<key column="username" not-null="true"/>
<one-to-many class="entry.Authority"/>
</set>
</class>
2)你将id作为权限中的外键: 在users.hbm.xml
中<key column="id" not-null="true"/>
,并在authority.hbm.xml中用
替换列用户名<property name="userId" column="userId"/>
您还必须修改数据库表。
答案 1 :(得分:1)
错误似乎来自权威映射。将其更改为具有反向引用
编辑:您可以使用propertyref告诉H加入另一个属性
<class name="entry.Authority" table="authorities">
<id name="id"/>
<many-to-one name="user" column="username" property-ref="username"/>
</class>
and
<set name="authorities" inverse="true" property-ref="username">
答案 2 :(得分:0)
如果使用JPA语法将是这样的(使拥有方不可更新): -
@JoinColumn(name = "", referencedColumnName = "", insertable = false, updatable = false)
问题是双向关系尝试再次更新列