I have one column for the time when object is created and one for when it is updated.
When I create and persist new object I get the error from MySQL:
updated cannot be null.
I didn't set any value to it because I want updated column to remain untouched and eventually get default database value whatever it is.
How to do tell doctrine to persist only those columns which values I explicitly set/changed?
Make sure your column definition has nullable defined as true.
/**
* #Column(type="datetime", nullable=true)
*/
protected $updated;
Then you should set your column in your entity to nullable false.
In your Entity:
/**
* #var datetime $date_updated
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $date_updated;
Related
I have my table information defined via the annotation of the entity. So I would like to change the following column to a TEXT instead of a STRING. So I had this:
/**
* #ORM\Column(type="string", length=255)
*/
private $category;
And I changed it to this:
/**
* #ORM\Column(type="text")
*/
private $category;
I expected it to become a TEXT, so after migrating I checked my database and it says it's a LONGTEXT. I have no idea how this is possible, but before referting my migrations, I would like to know how to make it a TEXT and not a LONGTEXT.
EDIT: I'm looking inside the migration file and I see this:
$this->addSql('ALTER TABLE cabinet CHANGE category category LONGTEXT NOT NULL');
I never typed LONGTEXT so I have no clue where Doctrine is getting that from.
The answer seems to be to give the length of TEXT as well (I thought it was defined as a fixed value), so instead of #ORM\Column(type="text") you should do #ORM\Column(type="text", length=65535). I was able to find this answer because of this other SO question.
If you want to change with migrations you need notate that converting to text will base on the current column length;
$table = $schema->getTable("tablename");
$column = $table->getColumn("columnname");
/** There you need set size of text that you want to use
* To TINYTEXT => length = 0 - 255
* To TEXT => length = 256 - 65535
* To MEDIUMTEXT = 65536 - 16777215
**/
$column->setLength('65535');
$column->setType(Type::getType(Types::TEXT))
It will change current type only if current type is not been Types::TEXT. If your text is tinytext and you need to set it to text, you need first to change type to string, set length and only then set it back to text.
How can I add tiny integer column using laravel migration to MySQL? I thought this code
$table->addColumn('tinyInteger', 'birth_day', ['lenght' => 2]);
But it creates TINYINT(4) column. I don't know how I can solve this problem. Please don't ask me why a day only, not full date. It is a business logic of the app.
It looks to me like you're spelling "length" wrong, maybe try $table->addColumn('tinyInteger', 'birth_day', ['length' => 2]);
/**
* Create a new tiny integer (1-byte) column on the table.
*
* #param string $column
* #param bool $autoIncrement
* #param bool $unsigned
* #return \Illuminate\Support\Fluent
*/
public function tinyInteger($column, $autoIncrement = false, $unsigned = false)
{
return $this->addColumn('tinyInteger', $column, compact('autoIncrement', 'unsigned'));
}
This is the tinyInteger() function from Blueprint.php. As you can see it expects a boolean parameter here. It looks like you're trying to add a argument for size. You cannot specify the size of tinyInt in Laravel.
Instead use
$table->tinyInteger('birth_day'); // `birth_day` tinyint(3)
I solve my problem by pure sql
DB::statement("ALTER TABLE `users`
ADD `birth_day` TINYINT(2) DEFAULT NULL AFTER `lastname`");
I want to map a property from one of my doctrine's entity to a table's column with datatype of YEAR.
At the moment I'm using the doctrine's integer type with the length of 4 as demonstrated bellow, but I was wondering if there is a better match for such mapping.
/**
* #var integer
*
* #ORM\Column(name="year", type="integer", length=4, nullable=true)
*/
private $year;
Any exact numeric type should be ok
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 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;
}
...
}