i have an object student. then there is a property called expiry date. this is need to be set with the database sysdate + a value(1000).
so how can i save with jpa. can't i do it on the jpa prepared statement query itself?
if i use sql.date is it exactly give the same value as when we are saving as 'sysdate'?
can't i do it with on the query itself?
other properties can be set to the object. but the problem is this expiry date as it needs the sysdate and add another value to it eg: expiry date = sysdate + 1000; how can i do it with jpa prepared statements. please reply me
What about use a seperate query to retrieve sysdate and set it to your object.
I usally create a Clock to handle this:
public interface Clock {
Date now();
}
public class HibernateClock implements Clock {
//use query to retieve the db sysdate
}
You can add it in java itself. Use calendar object to add days.
Calendar expirydate=Calendar.getInstance();
expirydate.add(Calendar.DATE, 1000);
then
expirydate.getTime() will give you expire date object.
Why do you want to use sysdate? Its syntax is database specific and also dependent on the DB-hosting machine's clock, rather than on your application-hosting machine's clock.
Easiest way is to use java.util.Date as the expiryDate's type and the value of new Date(System.currentTimeInMillis() + 1000). Use this value in the field's declaration for featuring it as default value on new Student creation or use it as the value passed to the setter when modifying an existant Student.
public class Student {
...
/**
* Using java.util.Date here. Hibernate knows to convert it automagically to java.sql.Date.
* Set default value to current time + 1 second, if this is your requirement.
*/
private Date expiryDate = new Date(System.currentTimeInMillis() + 1000);
public void setExpiryDate(final Date expiryDate) {
this.expiryDate = expiryDate;
}
...
}
Related
I have not yet understood where concretely is the problem is...
I have a Doctrine entity with date field:
/**
* #var \DateTime
*
* #ORM\Column(name="day", type="date")
*/
private $day;
Also I have an entity form with date type field:
$builder->add('day', DateType::class, ['widget' => 'single_text'])
And when I try to save the form with value "2016-02-14" I see that it becomes "2016-02-13" (a day earlier) in MySQL and in PHP after saving. When I began looking for logs, I saw that the query parameter value is "2016-02-13 23:00:00".
But I don't understand why it happens this way.
I have the same time and timezone in system (Ubuntu), PHP and MySQL (Europe/Moscow timezone).
I use date type, not datetime, so there should not be time at all.
When I tried to debug it, I saw that code
#vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return ($value !== null)
? $value->format($platform->getDateFormatString()) : null;
}
works correctly. It makes correct format "Y-m-d", but in the symfony log value is with time.
I need an advice about how to find, where my date transforms.
I had a similar problem and used a quick-and-dirty hack. On the setter used for the $day property, just set the time to be midday.
public function setDay(\DateTime $day)
{
$this->day = $day;
$this->day->setTime(12, 0, 0);
return $this;
}
I have a column in mysql database named time_start which type is TIME.
I am trying to format the displayed time in my view from H:i:s to simple H:i, so instead of 20:00:00 i will get 20:00.
Firstly i thought i can use format() method, but it's supposed to be used with timestamps, so of course i get error Call to a member function format() on a non-object.
I'm sure it's a simple question, but i can't solve this.
-EDIT-
Forgt to mention. I am working with a many to many relationship and i'm calling my data like:
$schedule->time_start
Here i would like to show the time in H:i format, not H:i:s.
Have you tried an accessor method? I.e. in the Schedule model,
/**
* Return a truncated version of the timestamp.
* #param $value original value of attribute
* #return string truncated value
*/
public function getTimeStartAttribute($value)
{
// Input is HH:MM:SS
return substr($value, 0, 5);
// Output is HH:MM
}
Then $schedule->time_start ought to return the time in HH:MM format.
I have 2 domain classes, Item and Manufacturer. The Manufacturer has a property on it to warn the user when the Item is about to expire (the date of which is stored as a Joda DateTime object). The relevant fields are set up like so.
class Manufacturer {
Integer expirationWarning
static hasMany = [items: Item]
}
and
class Item {
DateTime expirationDate
static belongsTo = [manufacturer: Manufacturer]
}
I'm trying to create a list of Items where the expiration is some time between now and now plus expirationWarning days. I have gotten the query working correctly in the MySQL terminal.
SELECT i.id FROM items as i
LEFT JOIN (manufacturer as m) ON (m.id = i.manufacturer_id)
WHERE i.expiration_date <= DATE_ADD(current_date, INTERVAL m.expiration_warning DAY);
Now I just need to execute the same query in Grails. I know that the createCriteria will look something like this:
def itemsExpiringSoon = Item.createCriteria().list(max: listMax, offset: params.offset) {
createAlias('manufacturer', 'm', CriteriaSpecification.LEFT_JOIN)
le('expirationDate', new DateTime().plusDays('m.expirationWarning'))
order('expirationDate', 'desc')
}
But I can't figure out what to put in place of 'm.expirationWarning' in order to use the value of that field in the DateTime.plusDays(). Any guidance on this would be incredibly helpful.
You cannot mix your query in this way, but the criteria have an option to add sql directly, then you can use your date_add().
def itemsExpiringSoon = Item.createCriteria().list(max: listMax, offset: params.offset) {
createAlias('manufacturer', 'm', CriteriaSpecification.LEFT_JOIN)
sqlRestriction('m.expiration_warning <= DATE_ADD(current_date, INTERVAL m.expiration_warning DAY)')
order('expirationDate', 'desc')
}
Note that in sqlRestriction() you write something that will be added in the final SQL, so we use the name of the database column, and not the attribute of the domain class.
Two and a half years later, I finally figured out a solution to this problem.
I created what is, in effect, a transient property that I applied GORM formulas to, that represents the current date plus the manufacturer specified expiration warning.
class Item {
Date expirationDate
Date pendingExpiration
static belongsTo = [manufacturer: Manufacturer]
static mapping = {
pendingExpiration formula: "(SELECT ADDDATE(current_date, mfr.expiration_warning) FROM manufacurer mfr WHERE mfr.id = manufacturer_id LIMIT 1)"
}
}
Now I can query against this property, and it will update dynamically as Manufacturer.expirationWarning does.
Not sure if I should raise an issue regarding this, so thought I would ask if anybody knew a simple workaround for this first. I am getting an error when I try to use Dapper with OleDbConnection when used in combination with MS Access 2003 (Jet.4.0) (not my choice of database!)
When running the test code below I get an exception 'OleDbException : Data type mismatch in criteria expression'
var count = 0;
using (var conn = new OleDbConnection(connString)) {
conn.Open();
var qry = conn.Query<TestTable>("select * from testtable where CreatedOn <= #CreatedOn;", new { CreatedOn = DateTime.Now });
count = qry.Count();
}
I believe from experience in the past with OleDb dates, is that when setting the DbType to Date, it then changes internally the value for OleDbType property to OleDbTimeStamp instead of OleDbType.Date. I understand this is not because of Dapper, but what 'could' be considered a strange way of linking internally in the OleDbParameter class
When dealing with this either using other ORMs, raw ADO or my own factory objects, I would clean up the command object just prior to running the command and change the OleDbType to Date.
This is not possible with Dapper as far as I can see as the command object appears to be internal. Unfortunately I have not had time to learn the dynamic generation stuff, so I could be missing something simple or I might suggest a fix and contribute rather than simply raise an issue.
Any thoughts?
Lee
It's an old thread but I had the same problem: Access doesn't like DateTime with milliseconds, so you have to add and extension method like this :
public static DateTime Floor(this DateTime date, TimeSpan span)
{
long ticks = date.Ticks / span.Ticks;
return new DateTime(ticks * span.Ticks, date.Kind);
}
And use it when passing parameters:
var qry = conn.Query<TestTable>("select * from testtable where CreatedOn <= #CreatedOn;", new { CreatedOn = DateTime.Now.Floor(TimeSpan.FromSeconds(1)) });
Unfortunately, with current Dapper version (1.42), we cannot add custom TypeHandler for base types (see #206).
If you can modify Dapper (use the cs file and not the DLL) merge this pull request and then you do not have to use Floor on each parameters :
public class DateTimeTypeHandler : SqlMapper.TypeHandler<DateTime>
{
public override DateTime Parse(object value)
{
if (value == null || value is DBNull)
{
return default(DateTime);
}
return (DateTime)value;
}
public override void SetValue(IDbDataParameter parameter, DateTime value)
{
parameter.DbType = DbType.DateTime;
parameter.Value = value.Floor(TimeSpan.FromSeconds(1));
}
}
SqlMapper.AddTypeHandler<DateTime>(new DateTimeTypeHandler());
I have a Flex screen (MXML) with two date fields (say, From and To date). Based on the date values, data has to be shown on the DataGrid. Here, I have to restrict the user on choosing the date value. A permitted range has to be set in the date field.
Eg, The default date for both date fields is "Today"
The permitted range for From Date is "Today - 7 to Today"
The permitted range for To Date is also "Today - 7 to Today"
How can I achieve this? Both by selecting the date picker as well as by entering the date value if the date field is set to editable
I would simply implement a custom DateValidator for this kind of logic especially that users can also type-in certain dates in invalid or not supported format.
ActionScript (pseudo-code):
public class RangeDateValidator extends DateValidator
{
[Bindable]
public var fromDate:String;
protected override function doValidation(value:Object):Array
{
// create a real date and apply your custom logic
// based on the fromDate value
}
}
MXML (pseudo-code):
<d:RangeDateValidator source="{ toDate }" property="text"
inputFormat="DD.MM.YYYY" fromDate="{ fromDate.text }" />
Let me know if this is working in your case