I am trying ORMLite as an ORM for a project I am developing. I am mapping a java class to a table that has some auditing fields (ie. updatedby, updatedtime, etc.). The auditing fields are maintained by the database using triggers to ensure that no matter what front-end the user is using these fields will always be correctly updated when a record is updated.
I need to include these fields in my client application to inform the user when the record was last updated, but the user can't change them. Is there a way to annotate the class so that ORMLite won't try to perform updates on these fields or include them in insert statements. The database will deny an update if these fields are included in an update statement (which is why I can't just write back the original value that was queried from the database).
I tried using the #DatabaseField(persisted = false) annotation on the Java fields, but then they don't get queried at all so the Java object is never populated with these fields.
Basically, I need these fields to be included in SELECT statements, but not included in INSERT or UPDATE statements (equivalent to a #DatabaseField(immutable = true) annotation).
Interesting pattern. ORMLite didn't support the feature at the time but now it does as of version 4.46.
There is now a #DatabaseField(readOnly=true) annotation field.
Related
Say I have EntityFramework Core 2.1.14.
Say I have to integrate data into a legacy MySql database which was created by a self-taught.
Say also that one of the tables in this database has a surrogate key field that is generated on Add.
Say then that I want to use context.SaveChanges() to handle the Insert DML generation for me because I want to be lazy and because these tables are messy.
Say finally that I do not want Entity Framework to perform a follow-up query to retrieve this surrogate field; I don't care what it is. I just need it generated on insert.
How would one call context.SaveChanges() with an Added object having a property configured as .ValueGeneratedOnAdd() but also instruct Entity Framework to do nothing but generate my INSERT ? I don't want it to return the id.
I am making a ZF2 app. I am using entities, mappers and services (e.g. UserEntity, UserMapper, UserService) to manage the objects/models. Properties in the entities are CamalCased (e.g. FirstName, LastName) while in the database, fields are using underscore (first_name, last_name). I will plan to use a hydrator to map the properties and db-fields when retrieving or saving. The service object (UserService) will be used to communicate with the mapper to retrieve and save data models using the mapper. The hydrator will convert the result of mapper and convert them into proper entities.
The thing I am confused is that when the service (UserService) need to provide some cirteria - for example to find all users with a specific 'last name', will the service use the database field names (last_name) or entity properties name (LastName)?
If the db field name is used in the Service, so any change in the db structure will require me to update the service also, which completely fails the reason of using the whole approach.
If you take a look at the ClassMethods:hydrate method (https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/Hydrator/ClassMethods.php) you will see that it just copies the properties from one object to another. You have the option of converting the property names to/from camelCase but that's it.
If you change a column name in your database then you will need to change corresponding property name in your object. And vice versa. Which I believe is the crux of your question?
If you want to make table column names be independent of your method names then you need something that lets you define an actual mapping table somewhere. Change a column or method name and you only need to update the configuration mapping table.
Not a ZF2 expert so I could be wrong but it doesn't look like any of the supplied hydrators support this.
I do know that Doctrine 2 supports it.
I would like to know validation is a must, on fields which are not present on the form but are available in the table. Does marking them as NULL in the define_table make them validated only when they are present in the form?
The form validators apply only to forms, so will not affect fields that are not present in the form. I'm not sure what you mean by marking a field as NULL, but if you are referring to Field(..., notnull=True), that executes the SQL NOT NULL statement when the database table is first created (assuming DAL migrations are enabled). That option is enforced by the database itself whenever a record is inserted or updated (via a form or any other method). If a notnull field is left empty, it will result in an operational error from the database.
None of the many questions on this topic seem to match my situation. I have a large data model. In certain cases, only a few of the fields need be displayed on the UI, so for those I replaced the LINQ to Entity query that pulls in everything with an Entity SQL query retrieving only the columns needed, using a Type constructor so that I got an entity returned and not a DbDataRecord, like this:
SELECT VALUE MyModelNameSpace.INCIDENT(incident.FieldA, incident.FieldB, ...) FROM ... AS ...
This works and displays the fields in the UI. And if I make a change, the change makes it back to the entity model when I tab out of the UI element. But when I do a SaveChanges, the changes do not get persisted to the database. No errors show up in the Log. Now if I very carefully replace the above query with an Entity Sql query that retrieves the entire entity, like this:
SELECT VALUE incident FROM MyDB.INCIDENTs AS incident...
Changes do get persisted in the database! So as a test, I created another query like the first that named every column in the entity, which should be the exact equivalent of the second Entity SQL query. Yet it did not persist changes to the database either.
I've tried setting the MergeOption on the returned result to PreserveChanges, to start tracking, like this:
incidents.MergeOption = MergeOption.PreserveChanges;
But that has no effect. But really, if retrieving the entire entity with Entity Sql persists changes, what logical purpose would there be for behaving differently when a subset of the fields are retrieved? I'm wondering if this is a bug?
Gert was correct, the problem was that the entity was not attached. Dank U wel, Gert! Ik was ervan verbluft!
I just wanted to add a little detail to show the full solution. Basically, the ObjectContext has an Attach method, so you'd think that would be it. However, when your Entity SQL select statement names columns, and you create the object using a Type as I did, the EntityKey is not created, and ObjectContext.Attach fails. After trying and failing to insert the EntityKey I created myself, I stumbled across ObjectSet.Attach, added in Entity Framework 4. Instead of failing, it creates the EntityKey if it is missing. Nice touch.
The code was (this can probably be done in fewer steps, but I know this works):
var QueryString = "SELECT VALUE RunTimeUIDesigner.INCIDENT (incident.INCIDENT_NBR,incident.LOCATION,etc"
ObjectQuery<INCIDENT> incidents = orbcadDB.CreateQuery<INCIDENT>(QueryString);
incidents.MergeOption = MergeOption.PreserveChanges;
List<INCIDENT> retrievedIncidents = incidents.ToList<INCIDENT>();
orbcadDB.INCIDENTs.Attach(retrievedIncidents[0]);
iNCIDENTsViewSource.Source = retrievedIncidents;
Using Entity Framework CodeFirst, how do I create a created datetime column that gets populated with the current timestamp everytime a record is inserted for that table, and a modified datetime column that has a timestamp generated evertime a row is updated? Rails does this by default and I was hoping the EF generated database would have this as well, but it doesn't. Is this something that can be done with data annotations? If so, how?
Thanks!
It is not supported in EF. EF will not create these columns for you automatically. You must do it yourselves by either:
Have Created and Modified properties in every entity where you want to maintain these values. You must also manually maintain these columns in your application (common approach is overriding SaveChanges and set values accordingly).
If you don't need these values mapped (you never expect to use them in your application and you are happy with the logic in the database) you can create custom database initializer which would execute your custom SQL to alter tables and add those columns, default constraints for Created columns and update triggers for Modified columns.