我是Hibernate的新手。 这是我的问题:
我有一个中央数据库,可以从很多代理重新组合数据。
每个代理商必须只将与他有关的数据存储在自己的数据库中。
我需要在服务器/代理之间同步数据
我有2个案例:
1)首次同步(代理上的DB为空)
2)完全同步(删除/添加新元素/更改等...)
我有一个盒子实体和用户实体,它们之间的关系是多对多
框实体的描述(部分)如下:
@Entity
//@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name="box")
@NamedQuery(name="Box.findAll", query="SELECT b FROM Box b")
@JsonIdentityInfo(generator= ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Box extends BasicData implements Serializable {
....
//bi-directional many-to-many association to User
@ManyToMany(mappedBy="boxs")
private Set<User> users;
//bi-directional many-to-one association to BoxUser
@OneToMany(mappedBy="box", orphanRemoval=true)
@Cascade({ org.hibernate.annotations.CascadeType.ALL})
private Set<BoxUser> boxUsers;
getters /setters
....
BoxUser实体(部分)描述如下:
public class BoxUser implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private BoxUserPK id;
//bi-directional many-to-one association to Box
@ManyToOne
@JoinColumn(name="boxid", nullable=false, insertable=false, updatable=false)
@Cascade({ org.hibernate.annotations.CascadeType.ALL})
private Box box;
//bi-directional many-to-one association to User
@ManyToOne
@JoinColumn(name="userid", nullable=false, insertable=false, updatable=false)
@Cascade({ org.hibernate.annotations.CascadeType.ALL})
private User user;
getters /setters
....
用户实体(部分)描述如下:
public class User extends BasicData implements Serializable {
private static final long serialVersionUID = 1L;
//bi-directional many-to-one association to BoxUser
@OneToMany(mappedBy="user")
private Set<BoxUser> boxUsers;
//bi-directional many-to-many association to Box
@ManyToMany
@JoinTable(
name="box_user"
, joinColumns={
@JoinColumn(name="userid", nullable=false)
}
, inverseJoinColumns={
@JoinColumn(name="boxid", nullable=false)
}
)
private Set<Box> boxs;
getters /setters
....
当我尝试保存/更新(我正在使用合并方法)时,代理端的数据我看到数据已插入但已立即删除。
我不明白为什么。这里是hibernate的输出:
Hibernate:
insert
into
box_user
(role, boxid, userid)
values
(?, ?, ?)
2015-05-20 15:14:23.818 TRACE: org.hibernate.type.EnumType - Binding [ADMIN_BOX] to parameter: [1]
2015-05-20 15:14:23.819 TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [BIGINT] - [1]
2015-05-20 15:14:23.819 TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [BIGINT] - [4]
Hibernate:
delete
from
box_user
where
userid=?
2015-05-20 15:14:23.831 TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [BIGINT] - [4]
这是进行同步的方法:
private void synchroUser(Box internalBox, Long boxId)
{
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
BoxUser[] remoteBUList = restTemplate.getForObject(DOMITIK_URL + RestURIConstant.DOMITIK_WS + "getboxuserbyboxid/{boxid}" ,BoxUser[].class,boxId);
if(internalBox == null)
{
boolean firstAdd = true;
for (BoxUser curBoxUser : remoteBUList)
{
// this avoid to save more than one time the box (exception occurred if trying to save several time.
if(!firstAdd)
curBoxUser.setBox(null);
boxUserService.mergeElement(curBoxUser);
firstAdd = false;
}
}
else
{
List<BoxUser> localBUList = boxUserService.findAll();
//deleting users that were removed from server
for (BoxUser localBoxUser : localBUList)
{
boolean userFound = false;
for (BoxUser remoteBoxUser : remoteBUList)
{
if(localBoxUser.getUser().getId() == remoteBoxUser.getUser().getId())
{
userFound = true;
break;
}
}
if(!userFound)
userService.deleteElement(localBoxUser.getUser());
}
//adding new users
for (BoxUser curBoxUser : remoteBUList)
{
boolean userFound = false;
for (BoxUser localBoxUser : internalBox.getBoxUsers())
{
if(localBoxUser.getUser().getId() == curBoxUser.getUser().getId())
{
userFound = true;
break;
}
}
if(!userFound)
{
curBoxUser.setBox(null);
boxUserService.mergeElement(curBoxUser);
}
}
}
}
我真的被困住了,需要了解我做错了什么......
感谢您的时间和帮助
答案 0 :(得分:0)
我猜测在您的配置中,您拥有值为hbm2ddl.auto
的属性"create-drop"
,会自动删除数据并在会话结束后删除架构
答案 1 :(得分:0)
我找到了解决问题的方法。
问题在于类的多级级别定义。
我删除了Box实体上的级联并将其保留在Box实体上:
' Generalized example for pulling integer portion from
' a textbox of the form 'a=12345'; amend as appropriate. Untested.
Dim a as integer
Dim receivedData as String
' Assuming txtBox1 as the name of the textbox in the client
receivedData = txtBox1.Text
receievedData = mid$(value,3)
a = Val(receivedData)
将其保留在BoxUser实体
上public class Box extends BasicData implements Serializable {
....
//bi-directional many-to-many association to User
@ManyToMany(mappedBy="boxs")
private Set<User> users;
//bi-directional many-to-one association to BoxUser
@OneToMany(mappedBy="box")
private Set<BoxUser> boxUsers;
现在它工作正常。
由于我是hibernate的新手,我希望这是一个很好的解决方案