我遇到了Validation
实例添加到Step
实例的问题。
声明如下:
步骤类:
@Entity
@Table
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Step extends AbstractEntity implements ValidatableStep {
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "step_id", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<Validation> validations = new HashSet<>();
@Override
public void addValidation(Validation validation) {
// do some stuff
...
// add validation instance to collection
getValidations().add(validation);
}
}
验证类:
@Entity
@Table
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Validation extends AbstractEntity {
//some properties
}
这两个类都是Cacheable
,并应用了READ_WRITE
策略。 Validation
的单向集合也采用相同的策略进行缓存。
可以预期,当调用addValidation(new Validation('userName'));
提交的读写事务时,新的Validation
将在后续的只读事务中可见。奇怪的是,有时它确实有效,有时它不起作用......
第一笔交易总是成功;我们看到新的验证存在于数据库中,而Step
的版本属性(用于乐观锁定目的)会增加。但有时,第二个读取事务包含一个Step
实例,其中包含空Validation
集合...
我们的Hibernate缓存配置如下:
hibernate.cache.use_second_level_cache = true
hibernate.cache.use_query_cache = true
hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.cache.provider_configuration_file_resource_path = classpath:ehcache.xml
net.sf.ehcache.hibernate.cache_lock_timeout = 10000
知道造成这种奇怪(和随机)行为的原因是什么?
答案 0 :(得分:1)
Hibernate Collection Cache始终使现有条目无效,并且实体和集合缓存共享相同的AbstractReadWriteEhcacheAccessStrategy,因此更新数据时soft-lock is acquired。
因为您使用的是单向一对多关联,所以最终会得到一个 public List<User> UserList = new List<User>();
public MainWindow()
{
InitializeComponent();
}
private void PressedEnter(object sender, KeyEventArgs e)
{
TextBox CurrentTextbox = (TextBox)sender;
if (e.Key == Key.Enter)
{
switch (CurrentTextbox.Name)
{
case "EnterName":
EnterBirthday.Focus();
break;
case "EnterBirthday":
EnterEmail.Focus();
break;
case "EnterEmail":
MainDataGrid.ItemsSource = null;
MainDataGrid.ItemsSource = UserList;
break;
}
}
}
private void AddButton_OnClick(object sender, MouseButtonEventArgs e)
{
MainDataGrid.ItemsSource = null;
MainDataGrid.ItemsSource = UserList;
}
private List<User> AddItemToGrid()
{
string[] NameArray = EnterName.Text.Split(' ');
string[] BirthdayArray = EnterBirthday.Text.Split('.');
UserList.Add(new User()
{
FirstName = NameArray[0],
LastName = NameArray[1],
Birthday = new DateTime(Convert.ToInt16(BirthdayArray[2]), Convert.ToInt16(BirthdayArray[1]), Convert.ToInt16(BirthdayArray[0])),
Email = EnterEmail.Text
});
return UserList;
}
表和一个Step_validation链接表。无论何时添加/删除验证,您都必须点击两个表并且效率较低。
我建议您在public class User
{
public string FirstName
{
get;
set;
}
public string LastName
{
get;
set;
}
public DateTime Birthday
{
get;
set;
}
public string Email
{
get;
set;
}
}
实体中添加<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="287*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="235" />
<ColumnDefinition Width="337*" />
</Grid.ColumnDefinitions>
<Label Grid.ColumnSpan="2"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Background="#2196f3"
BorderBrush="Transparent"
Content="DataGrid"
FontFamily="Roboto"
FontSize="15"
FontWeight="Bold"
Foreground="White" />
<StackPanel Grid.Row="1" Grid.Column="0">
<Label Height="25"
Margin="10,10,10,0"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
Background="#2196f3"
BorderBrush="Transparent"
Content="Name"
FontFamily="Roboto"
FontSize="13"
FontWeight="Bold"
Foreground="White" />
<TextBox Name="EnterName"
Height="25"
Margin="10,5,10,0"
VerticalAlignment="Top"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
BorderBrush="#2196f3"
FontFamily="Roboto"
Foreground="#2196f3"
KeyDown="PressedEnter" />
<Label Height="25"
Margin="10,10,10,0"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
Background="#2196f3"
BorderBrush="Transparent"
Content="Birthday (DD.MM.YYYY)"
FontFamily="Roboto"
FontSize="13"
FontWeight="Bold"
Foreground="White" />
<TextBox Name="EnterBirthday"
Height="25"
Margin="10,5,10,0"
VerticalAlignment="Top"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
BorderBrush="#2196f3"
FontFamily="Roboto"
Foreground="#2196f3"
KeyDown="PressedEnter"
MaxLength="10" />
<Label Height="25"
Margin="10,10,10,0"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
Background="#2196f3"
BorderBrush="Transparent"
Content="E-Mail"
FontFamily="Roboto"
FontSize="13"
FontWeight="Bold"
Foreground="White" />
<TextBox Name="EnterEmail"
Height="25"
Margin="10,5,10,0"
VerticalAlignment="Top"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
BorderBrush="#2196f3"
FontFamily="Roboto"
Foreground="#2196f3"
KeyDown="PressedEnter" />
<Label Name="AddButton"
Height="68"
Margin="10,10,10,10"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Background="#2196f3"
BorderBrush="#2196f3"
Content="ADD"
FontFamily="Roboto"
FontSize="30"
FontWeight="Bold"
Foreground="White"
MouseLeftButtonDown="AddButton_OnClick" />
</StackPanel>
<DataGrid Name="MainDataGrid"
Grid.Row="1"
Grid.Column="1" />
</Grid>
一面,并将Validation
一面转换为已映射的集合:
@ManyToOne