I'm using gorm and have a model like so:
type MyModel struct {
CreationTime time.Time
UpdateTime time.Time
}
I realized after deploying my DB that creation time and update time weren't adding times when items were being created and updated! I tried to fix this by updating the model to the following:
type MyModel struct {
CreationTime time.Time `gorm:"default:current_timestamp"`
UpdateTime time.Time `gorm:"default:current_timestamp ON update current_timestamp"`
}
However, auto migrating like the following won't apply these defaults on the already existing tables!
db.AutoMigrate(&MyModel{})
Is there any way I can use the built in migration functions to add defaults to columns? I searched the docs and it seems like I can only change the type of existing columns! If not, any recommendations for a why to simply add defaults to a column via migrations?
Have you tried sql tag?
`sql:"DEFAULT:current_timestamp"`
The automigration provided by gorm doesn't delete or modify your columns and for good reasons, it's not safe.
I had a similar issue. I needed to drop the null constraint from one of my columns and couldn't find anything that does that in gorm, and I'm pretty sure it doesn't. I wrote my own function for doing this. You can easily do something similar.
Please take a look at these two commits: this and this. What you can basically do this is to define a method for the Dialect interface and then write an implementation for that method for the commonDialect type (and the postgres type, if required).
Hope this helps. Feel free to ask me if you face any problems with implementation or have any doubts.
Related
How can I tell JPA how to behave with different column types in my database when it tries to generate the entities from tables?
For example when I have a column like the following in my MySQL:
`deleted` tinyint(1) NOT NULL DEFAULT 0,
I want in the generated entity by JPA have boolean instead of byte, but what the JPA will generate is something like this:
#Column(nullable=false)
private byte deleted;
However I want to have something like this:
#Column(nullable=false)
#Type(type = "org.hibernate.type.NumericBooleanType")
private boolean deleted;
I think there must be a way that I tell JPA how to translate the column types in my tables in the entities in Java!?
I don't like to modify the entities by hand!
If you're asking how to configure the Eclipse wizard to map TINYINT onto boolean, the answer is you probably cannot.
Using Hibernate tools looks more promising, though. There's a hibernate.reveng.xml config file you can use to control type mapping.
As a side note:
I don't like to modify the entities by hand!
Note that reverse engineering tools in general lack the business knowledge required to generate a business model structure that is completely sensible. You will likely have to do some tweaking (e.g you likely won't get any #ManyToMany associations, even if they are the more natural solution domain-wise).
In the last page of that wizard we can define the expected type for each column. The interesting part is, eclipse stores somehow the selected types for each column and in the future when you try to regenerate the entities you don't need to do this step times to times!
I know this question might have been asked before but I have not found a single answer yet.
Basically I am using entity framework and I am in need of selecting data from a database without knowing the name of the table, as this will be generic.
Now if I do not know the table name, I do not know the type too as I have tried using context.Database.SQLQuery or context.Database.ExecuteSQLStatement but these all require the type of the object it should be expecting.
All I am receiving as parameters are the name of the table and the row ID.
Could anybody give me further advice?
Thanks.
#
Edit:
I have just been notified that the only property I would need from this table is the Name field...
I have some Hibernate code running against a Postgres 9.5 DB, which looks like roughly like below (anonymized) -
Integer myEntityId = myEntity.getId();
getCurrentSession().evict(myEntity);
myEntity.setId(null);
MyEntity clonedMyEntity = (MyEntity)getCurrentSession().merge(myEntity);
myEntity.setMyBooleanField(false);
getCurrentSession().save(myEntity);
I have an entity myEntity with a large number of fields. I want to create a duplicate of the record with only 1 field value changed. To achieve this, I evict the entity from session, set Primary Key to null, merge it back to session, set the field I want to change, and then save the entity to DB. However, this code (which was working correctly for some time), is not working now. It sees incorrect value for the boolean field I am trying to modify - as a result violating some database constraints. Please help me fix this or suggest a better way to achieve what I am trying.
The error was happening not on adding this record but on add of another record to an audit table, triggered by the addition of this record. A coworker suggested me to use Eclipse Breakpoint view and use the add breakpoint option there and select the ConstraintViolationException class - this helped me to see the error for which trigger was failing and why and accordingly modify the data to suit the database constraint.
I'm trying to generate JPA entities from tables using eclipse plugins, I defined some BIG INT and Date columns. I would like to have long type in Entity class for those BIGINT columns, But It generates as String. Please help me how to resolve it?
Sounds really weird that the Eclipse plugin generates those columns as String - check that you haven't missed / misread something.
If the column really is a BIG INTEGER in the database, just changing the type of the property field to Long should do the trick.
I don't know exactly what do you mean long properties, but try to use #Type annotation. Example:
#Type(type = "org.hibernate.type.LongType")
I've found two ways of concurrency checking for my entities in EF 4.1:
TimeStamp attribute for byte array
ConcurrencyCheck attribute for another types
The first one is very simple. You just mark byte array property as TimeStamp, create additional column in database and voila...
I've got a problem with the second method. Enity Framework has started generate sql script for concurrency check, when I marked the LastUpdateDate property.
Property:
[ConcurrencyCheck]
public DateTime LastUpdateDate { get; set; }
Sql:
select
...
where (([Id] = #3) and ([LastUpdateDate] = #4))
...
#4='value'
But EF does not generate sql script for updating the value of LastUpdateDate?
Is it possible to say EF to update the LastUpdateDate after concurrency checking without triggers or something like this?
And the second question:
What is the best practice of using concurrency checking in EF when you have something like LastUpdateDate property(property will be displayed in UI)? Is it better to check concurency using LastUpdateDate and avoid creating of addtional column for TimeStamp in your tables or
create additional TimeStamp property and renounce of the using DateTime property for concurrency checking?
Have you tried to use a rowversion (timestamp) instead of the DateTime datatype to check for concurency?
I would use the timestamp, because you are sure that the system will update it for you. Further more the value will be very precice.
The following blog posts will give you more information about how to map a timestamp.
The first one shows how to use the timestamp as a concurrency check.
Code First Optimistic Concurrency with Fluent Assertions
Round tripping a timestamp field with EF4.1 Code First and MVC 3