Ebean update modifies field with #CreateTimestamp annotation - playframework-2.1

I have an abstract class that all my persisted objects extends from, see below. The creationDate and modifiedDate fields are populated when the an object is initially saved, I can see the dates in the table. The issue I'm having is when I update the same object both creationDate and the modifiedDate are also updated, what I want is only the modifiedDate field to be updated.
I'm using play 2.1 with ebean.
The abstract class ...
#MappedSuperclass
public abstract class BasePersistableEntity extends Model {
#Temporal(TemporalType.TIMESTAMP)
#Formats.DateTime(pattern="yyyy-MM-dd HH:mm:ss")
#CreatedTimestamp
protected Date creationDate;
#Temporal(TemporalType.TIMESTAMP)
#Formats.DateTime(pattern="yyyy-MM-dd HH:mm:ss")
#UpdatedTimestamp
#Version
protected Date modifiedDate;
public Date getCreationDate(){
return creationDate;
}
public void setCreationDate(Date date){
creationDate = date;
}
public Date getModifiedDate(){
return modifiedDate;
}
public void setModifiedDate(Date date){
modifiedDate = date;
}
}
Thanks.

#Temporal(TemporalType.TIMESTAMP)
#Formats.DateTime(pattern="yyyy-MM-dd HH:mm:ss")
#CreatedTimestamp
#Column(updatable=false)
protected Date creationDate;
Just add the #Column(updatable=false) annotation to the creationDate field

Related

QueryOver With Custom Projection and Query Parameter

I've defined a query in a class with a property, but am trying to build a fairly complex query using the property and have run into NHibernate telling me that it could not resolve property: DueDate.
My Query class looks like this:
public class SomeQuery {
public DateTime DueDate { get; private set; }
public SomeQuery(DateTime dueDate) {
DueDate = dueDate;
}
public QueryOver GetQueryOver() {
PrimaryObject po = null;
SubObject so = null;
return QueryOver.Of<PrimaryObject>(() => po)
.JoinAlias(() => so.SubObjects, () => so)
.Where(
Restrictions.Le(
DateProjections.DateDiff("d", () so.Value, () = DueDate),
0
)
);
}
}
I've implemented the DateProjections Class exactly as described in Andrew Whitaker's blog QueryOver Series - Part 7: Using SQL Functions
The contents of the PrimaryObject and SubObject aren't really important to the example except in the following:
public class PrimaryObject {
public virtual Guid Id { get; set; }
public List<SubObject> Implementations { get; set; }
}
public class SubObject {
public virtual Guid Id { get; set; }
public virtual string Value { get; set; }
}
For Mappings, you can assume that these fields are mapped to the database in sensible ways, as I don't feel like that is where the issue is.
When I try to use this query in a test, like the following:
var testDate = new DateTime(2015, 06, 01);
IEnumerable<PrimaryObject> result = repository.FindAll(new SomeQuery(testDate));
I get a NHibernate.QueryException:
NHibernate.QueryException : could not resolve property: DueDate of: PrimaryObject
Clearly, I've got an unmapped property, and that is causing the projection to have heartburn.
Looking for a minimal ceremony solution to getting the DueDate mapped. I've looked at Andrew's examples in QueryOver Series - Part 9: Extending QueryOver to Use Custom Methods and Properties, but it felt like a lot of ceremony.
I've also googled for solutions, but my google foo failed me..
Suggestions? Solutions?
The DateDiff implementation on the blog is assuming you wish to calculate the difference between database fields. This isn't what you want: you want to compare one database field with a constant.
You'll have to refactor the set of DateProjections methods to allow you to pass a constant as a parameter:
public static class DateProjections
{
private const string DateDiffFormat = "datediff({0}, ?1, ?2)";
// Here's the overload you need
public static IProjection DateDiff
(
string datepart,
Expression<Func<object>> startDate,
DateTime endDate
)
{
return DateDiff(
datePart,
Projections.Property(startDate),
Projections.Constant(endDate)
);
}
// Keeping Andrew Whitaker's original signature
public static IProjection DateDiff
(
string datepart,
Expression<Func<object>> startDate,
Expression<Func<object>> endDate
)
{
return DateDiff(
datePart,
Projections.Property(startDate),
Projections.Property(endDate)
);
}
// Added a function that's shared by
// all of the overloads
public static IProjection DateDiff(
string datepart,
IProjection startDate,
IProjection endDate)
{
// Build the function template based on the date part.
string functionTemplate = string.Format(DateDiffFormat, datepart);
return Projections.SqlFunction(
new SQLFunctionTemplate(NHibernateUtil.Int32, functionTemplate),
NHibernateUtil.Int32,
startDate,
endDate);
}
}
Now you can invoke it like so:
public QueryOver GetQueryOver() {
PrimaryObject po = null;
SubObject so = null;
return QueryOver.Of<PrimaryObject>(() => po)
.JoinAlias(() => so.SubObjects, () => so)
.Where(
Restrictions.Le(
DateProjections.DateDiff("d", () => so.Value, DueDate),
0
)
);
}

How do I make a datamember optional on deserialization?

I have an xml where the TimeStamp is not set. I have tried every possible combination here but on deserialization it always throws an exception with: There was an error deserializing the object of type MyType. The value '' cannot be parsed as the type 'DateTime'.
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public DateTime TimeStamp = DateTime.Now;
What exactly do I need to set on this TImeStamp member so that it is optional on deserialization (=not needed to be in the xml)
EDIT: What I tried on Xaruth's suggestion:
[DataMember]
[DefaultValue(typeof(DateTime), "2014-08-25T09:31:09.2477328+02:00")]
public DateTime TimeStamp { get; set; }
public bool ShouldSerializeTimeStamp()
{
return TimeStamp != null;
}
public void ResetTimeStamp()
{
TimeStamp = DateTime.Now;
}
You can use methods SouldSerialize and Reset, wich can be define for any properties.
For a property called TimeStamp, you can write methods SouldSerializeTimeStamp and ResetTimeStamp
According to MSDN, ResetTimeStamp will give you a default value for TimeStamp and SouldSerializeTimeStamp will be used to serialize or not TimeStamp.

Automapper resolveusing not returning nulls

I'm working on an MVC 4 project and trying to convert a value in a KeyValue list to a nullable DateTime. I have used the following line in the mapper (I've not included the other properties as there are a lot)
.ForMember(d => d.Deadline, m => m.ResolveUsing<DeadlineResolver>())
My resolver looks like this:
public class DeadlineResolver : ValueResolver<Booking, DateTime?>
{
protected override DateTime? ResolveCore(Booking source, ResolutionResult resolutionResult)
{
KeyValue keyValue = source.KeyValues.FirstOrDefault(k => k.Key.KeyId == "DEADLINE");
return (keyValue != null) ? DateTime.Parse(keyValue.Value) : (DateTime?)null;
}
}
The value of deadline which is defined as shown below is never returned as null but DateTime.MinDate instead. I need it to be null when I'm the binding the result in a view so that I only show a value when there is a date.
public DateTime? Deadline { get; set; }
How do I make these values null without going over the values after mapping to look for min dates and set to null (temp hack I've put in place so the code runs)?
Using LinqPad and AutoMapper 2.2.1 the following gives me a valid date when KeyValue has a date, and a null DateTime when KeyValue is null. (Note there are minor changes to the resolver to simplify it as the class definitions weren't provided).
void Main()
{
AutoMapper.Mapper.CreateMap<Booking, dest>()
.ForMember(d => d.Deadline, m => m.ResolveUsing<DeadlineResolver>());
AutoMapper.Mapper.AssertConfigurationIsValid();
// Gives a valid DateTime
var booking = new Booking { KeyValue = "2013-01-01" };
booking.Dump();
var rc = AutoMapper.Mapper.Map<Booking, dest>(booking);
rc.Dump();
// Gives a null DateTime
booking = new Booking { KeyValue = null };
booking.Dump();
rc = AutoMapper.Mapper.Map<Booking, dest>(booking);
rc.Dump();
}
// Define other methods and classes here
public class Booking
{
public string KeyValue { get; set; }
}
public class dest
{
public DateTime? Deadline { get; set; }
}
public class DeadlineResolver : AutoMapper.ValueResolver<Booking, DateTime?>
{
protected override DateTime? ResolveCore(Booking source)
{
return (source.KeyValue != null)
? DateTime.Parse(source.KeyValue)
: (DateTime?)null;
}
}
Is this the functionality you were after? If so, then the issue could be with an older version of AutoMapper, or an unexpected KeyValue value.

NHibernate - Why my DateTime property is always DateTime.MinValue

I have a [DataContract] called ReportRequest with a
NOT NULL column 'SubmittedAt'. So my DataContract looks something like:
[DataContract]
public class ReportRequest
{
Int32 templateId;
DateTime submittedAt = DateTime.Now;
[DataMember]
public virtual Int32? Id
{
get;
set;
}
public virtual DateTime SubmittedAt
{
get {
return submittedAt;
}
set
{
submittedAt = value;
}
}
}
Because, I have taken a private variable submittedAt and is initialised with DateTime.Now,
shouldn't the SubmittedAt property have the same value??
But when i am calling NHibernate
session.Save(objReportRequest);
I am getting the error:
SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
Any thoughts why I am getting this error?
As a workaround for now I have changed getter for SubmittedAt property as:
get {
if (submittedAt == DateTime.MinValue)
return DateTime.Now;
else
return submittedAt;
}
SQL Server minimum DateTime value is bigger than DateTime.Min value. So you cannot save minimum value to database.
As Marek Tihkan already said: SqlServer can not store the DateTime.MinValue, it is outside of the value range of SqlServer's DateTime data type.
The best advise is to use nullable types anyway:
[DataContract]
public class ReportRequest
{
DateTime? submittedAt = null;
public virtual DateTime? SubmittedAt
{
get {
return submittedAt;
}
set
{
submittedAt = value;
}
}
}
By SubmittedAt.HasValue you know if it is actually set to something reasonable. You shouldn't depend on some "magic values" to decide if a value is initialized or not.
It's because DateTime.MinValue doesn't have the same meaning as the minimum value you could store in a SQL Server datetime column. In SQL server datetime column the minimum date you could store is the one you get in your exception stack. It is SqlDateTime.MinValue

How to persist an enum using NHibernate

Is there a way to persist an enum to the DB using NHibernate? That is have a table of both the code and the name of each value in the enum.
I want to keep the enum without an entity, but still have a foreign key (the int representation of the enum) from all other referencing entities to the enum's table.
Why are you guys over complicating this? It is really simple.
The mapping looks like this:
<property name="OrganizationType"></property>
The model property looks like this:
public virtual OrganizationTypes OrganizationType { get; set; }
The Enum looks like this:
public enum OrganizationTypes
{
NonProfit = 1,
ForProfit = 2
}
NHibernate will automatically figure it all out. Why type more than you need????
You can use the enum type directly: http://web.archive.org/web/20100225131716/http://graysmatter.codivation.com/post/Justice-Grays-NHibernate-War-Stories-Dont-Use-Int-If-You-Mean-Enum.aspx. If your underlying type is a string, it should use the string representation, if it is numeric, it will just use the numeric representation.
But your question wording sounds like you're looking for something different, not quite an enum. It seems that you want a lookup table without creating a separate entity class. I don't think this can be done without creating a separate entity class though.
An easy but not so beautiful solution:
Create an integer field with and set the mapping in the mapping file to the field.
Create a public property that uses the integer field.
private int myField;
public virtual MyEnum MyProperty
{
get { return (MyEnum)myField; }
set { myField = value; }
}
I am using NHibernate 3.2, and this works great:
type="NHibernate.Type.EnumStringType`1[[enum_full_type_name, enum_assembly]], NHibernate"
Not sure when the generic EnumStringType got added, though.
Try using a stategy pattern. Uou can then put logic into your inner classes. I use this quite alot espically when there is logic that should be contained in the "enum". For example the code below has the abstract IsReadyForSubmission() which is then implemented in each of the nested subclasses (only one shown). HTH
[Serializable]
public abstract partial class TimesheetStatus : IHasIdentity<int>
{
public static readonly TimesheetStatus NotEntered = new NotEnteredTimesheetStatus();
public static readonly TimesheetStatus Draft = new DraftTimesheetStatus();
public static readonly TimesheetStatus Submitted = new SubmittedTimesheetStatus();
//etc
public abstract int Id { get; protected set; }
public abstract string Description { get; protected set; }
public abstract bool IsReadyForSubmission();
protected class NotEnteredTimesheetStatus: TimesheetStatus
{
private const string DESCRIPTION = "NotEntered";
private const int ID = 0;
public override int Id
{
get { return ID; }
protected set { if (value != ID)throw new InvalidOperationException("ID for NotEnteredTimesheetStatus must be " + ID); }
}
public override string Description
{
get { return DESCRIPTION; }
protected set { if (value != DESCRIPTION)throw new InvalidOperationException("The description for NotEnteredTimesheetStatus must be " + DESCRIPTION); }
}
public override bool IsReadyForSubmission()
{
return false;
}
}
//etc
}