我有一个简单的Persistable Class:
[assembly: ExportRenderer(typeof(ListView2), typeof(ListView2Renderer))]
namespace MyProject.iOS
{
public partial class ListView2Renderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (Control != null && e != null)
{
//oldDelegate = (UITableViewSource)Control.Delegate;
Control.Delegate = new ListView2Delegate(e.NewElement);
}
}
}
class ListView2Delegate : UITableViewDelegate
{
private ListView _listView;
internal ListView2Delegate(ListView listView)
{
_listView = listView;
}
public override void WillDisplay(UITableView tableView, UITableViewCell cell, Foundation.NSIndexPath indexPath)
{
cell.SelectedBackgroundView = new UIView()
{
BackgroundColor = Color.Red.ToUIColor()
};
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_listView = null;
}
base.Dispose(disposing);
}
}
}
一个简单的存储库:
public class Profile implements Persistable<String>{
@Id
private String username;
@CreatedDate
public Date createdDate;
public Profile(String username) {
this.username = username;
}
@Override
public String getId() {
return username;
}
@Override
public boolean isNew() {
return username == null;
}
}
我的Spring Boot Application类也注明了@EnableMongoAuditing。但是我仍然无法获得注释@CreatedDate的工作。
ProfileRepository.save(新的配置文件(&#34; user1&#34;))写入没有字段createdDate的实体。我做错了什么?
编辑:这是我的Application类(没有@EnableMongoRepositories,但它可以工作,因为存储库在子包中我猜)
public interface ProfileRepository extends MongoRepository<Profile, String> {
}
编辑:添加注释EnableMongoRepositories也没有改变任何内容。
答案 0 :(得分:2)
我自己遇到了这个问题,因为你自己创建了这个问题。
public Profile(String username) {
this.username = username;
}
通过这样做,mongo认为它不是一个新对象,并且不使用@CreatedDate注释。您还应该使用@Document注释而不是实现Persistable Class,如下所示:
@Document
public class Profile{}
答案 1 :(得分:1)
如果那是你真正的班级(Profile
),那么你无法用标准工具做任何事情。
您的isNew
方法将始终返回false
,因为您自己设置了用户名,而当Profile
即将被Spring保存时,它会检查isNew
和你可能已经设置了username
。 @LastModifiedDate
适用于您的情况,但@CreatedDate
不会。
如果你没有其他字段可以在isNew
方法中使用,那么你必须手动设置createdDate
的值(或者可能有某种拦截器可以包装所有mongo模板方法,但我不会这样做。)
例如,检查DB中是否已存在具有给定用户名的配置文件,如果是这样,只需获取它的createdDate(您可以在此处使用投影)并设置为您要保存的配置文件。否则将createdDate设置为新日期。
答案 2 :(得分:1)
您只需将@Version字段添加到@Document类中,并启用@EnableMongoAuditing
。看起来像这样:
@Document
public class Profile implements Persistable<String>{
@Vesrion
private Long version;
@Id
private String username;
@CreatedDate
public Date createdDate;
public Profile(String username) {
this.username = username;
}
@Override
public String getId() {
return username;
}
@Override
public boolean isNew() {
return username == null;
}
}
答案 3 :(得分:1)
如 Spring Data MongoDB 问题 DATAMONGO-946 中所述,创建日期功能使用 isNew()
方法来确定是否应设置创建日期,因为实体是新的。在您的情况下,您的 isNew
方法始终返回 false,因为始终设置 username
。
问题中的评论为这个问题提供了两种可能的解决方案。
Persistable
解决方案第一个选项是修复 isNew
策略,以便它正确注册新对象。评论中建议的一种方法是更改实现以检查 createdDate
字段本身,因为它应该只在非新对象上设置。
@Override
public boolean isNew() {
return createdDate == null;
}
第二个选项是从实现 Persistable
改为使用持久化实体,并使用 @Version
注释在持久化 MongoDB 实体中注入 version
属性。请注意,这将改变数据的持久化方式,因为它会向数据添加一个自动递增的 version
字段。
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class Profile {
@Id
private String username;
@CreatedDate
public Date createdDate;
@Version
public Integer version;
public Profile(String username) {
this.username = username;
}
}
答案 4 :(得分:0)
对我来说,我只是这样做:
@CreatedDate
@Field("created_date")
@JsonIgnore
private Instant createdDate = Instant.now();
并确保“获取/设置”可用。 希望有帮助
答案 5 :(得分:0)
我有一个类似的情况,有时我需要手动设置ID,并且确实没有办法事先知道ID是一个新的ID还是一个更新,而无需事先搜索数据库。我还知道,在实体的整个生命周期中,我将多次更新我的实体,但是只创建一次。因此,为了避免额外的数据库操作,我采用了以下解决方案:
80
80
80
80
这是利用了我在Profile上也有一个public class Regex {
static boolean range(int timeval,int min,int max)
{
boolean status=false;
if(timeval>=min && timeval<max)
{status=true;}
return status;
}
public static void main(String[] args) {
String regex = "[0-9]{1,2}";
String input ="23:59:59";
String msg="please enter valid time ";
String[] inputString = input.split(":");
if(inputString[0].matches(regex) && inputString[1].matches(regex) && inputString[2].matches(regex) )
{
if(Regex.range(Integer.parseInt(inputString[0]), 00, 24) &&Regex.range(Integer.parseInt(inputString[1]), 00, 60) && Regex.range(Integer.parseInt(inputString[2]), 00, 60))
{msg="converted time = " + Integer.parseInt(inputString[0]) + " : " +Integer.parseInt(inputString[1])+ " : " +Integer.parseInt(inputString[2]) ;}
}
System.out.println(msg);
}
}
字段的事实,保存实体时该字段总是由spring数据更新。