How to ignore an entity field in Spring Data Cassandra? - spring-data-cassandra

How do I ignore an entity field in Spring Data Cassandra? Using the javax.persistence.Transient annotation?

Try annotating your transient fields with org.springframework.data.annotation.Transient and report back whether that works.
So, I wrote a test adding three fields:
#javax.persistence.Transient
private Boolean one;
#org.springframework.data.annotation.Transient
private Boolean two;
private Boolean three;
to an entity to Cassandra. Result:
one was populated.
two was not populated.
three was populated. (just a check that I got my changes through)
Conclusion:
javax.persistence.Transient will not ignore a field.
org.springframework.data.annotation.Transient will ignore a field.
If it does, you get bonus points for creating a test for it and sending a pull request!
Sorry, I'm on a tight schedule and don't know the code well enough. Created a JIRA ticket, though!

I don't recall explicitly coding this into spring-data-cassandra, but that behavior might just be provided entirely by spring-data-commons. I don't have time right now to create a test for that, though.
Try annotating your transient fields with org.springframework.data.annotation.Transient and report back whether that works. If it does, you get bonus points for creating a test for it and sending a pull request! :)

Related

Extending a JOOQ Table class

I have a 'document' table (very original) that I need to dynamically subset at runtime so that my API consumers can't see data that isn't legal to view given some temporal constraints between the application/database. JOOQ created me a nice auto-gen Document class that represents this table.
Ideally, I'd like to create an anonymous subclass of Document that actually translates to
SELECT document.* FROM document, other_table
WHERE document.id = other_table.doc_id AND other_table.foo = 'bar'
Note that bar is dynamic at runtime hence the desire to extend it anonymously. I can extend the Document class anonymously and everything looks great to my API consumers, but I can't figure out how to actually restrict the data. accept() is final and toSQL doesn't seem to have any effect.
If this isn't possible and I need to extend CustomTable, what method do I override to provide my custom SQL? The JOOQ docs say to override accept(), but that method is marked final in TableImpl, which CustomTable extends from. This is on JOOQ 3.5.3.
Thanks,
Kyle
UPDATE
I built 3.5.4 from source after removing the "final" modifier on TableImpl.accept() and was able to do exactly what I wanted. Given that the docs imply I should be able to override accept perhaps it's just a simple matter of an erroneous final declaration.
Maybe you can implement one of the interfaces
TableLike (and delegate all methods to a JOOQ implementation instance) such as TableImpl (dynamic field using a HashMap to store the Fields?)
Implement the Field interface (and make it dynamic)
Anyway you will need to remind that there are different phases while JOOQ builds the query, binds values, executes it etc. You should probably avoid changing the "foo" Field when starting to build a query.
It's been a while since I worked with JOOQ. My team ended up building a customized JOOQ. Another (dirty) trick to hook into the JOOQ library was to use the same packages, as the protected identifier makes everything visible within the same package as well as to sub classes...

Retrieving a value object without Aggreteroot

I'm developing an application with Domain Drive Design approach. in a special case I have to retrieve the list of value objects of an aggregate and present them. to do that I've created a read only repository like this:
public interface IBlogTagReadOnlyRepository : IReadOnlyRepository<BlogTag, string>
{
IEnumerable<BlogTag> GetAllBlogTagsQuery(string tagName);
}
BlogTag is a value object in Blog aggregate, now it works fine but when I think about this way of handling and the future of the project, my concerns grow! it's not a good idea to create a separate read only repository for every value object included in those cases, is it?
anybody knows a better solution?
You should not keep value objects in their own repository since only aggregate roots belong there. Instead you should review your domain model carefully.
If you need to keep track of value objects spanning multiple aggregates, then maybe they belong to another aggregate (e.g. a tag cloud) that could even serve as sort of a factory for the tags.
This doesn't mean you don't need a BlogTag value object in your Blog aggregate. A value object in one aggregate could be an entity in another or even an aggregate root by itself.
Maybe you should take a look at this question. It addresses a similar problem.
I think you just need a query service as this method serves the user interface, it's just for presentation (reporting), do something like..
public IEnumerable<BlogTagViewModel> GetDistinctListOfBlogTagsForPublishedPosts()
{
var tags = new List<BlogTagViewModel>();
// Go to database and run query
// transform to collection of BlogTagViewModel
return tags;
}
This code would be at the application layer level not the domain layer.
And notice the language I use in the method name, it makes it a bit more explicit and tells people using the query exactly what the method does (if this is your intent - I am guessing a little, but hopefully you get what I mean).
Cheers
Scott

session.evaluate and notesxspdocument

I have question regarding session.evaluate in SSJS. In a keyword document I have some #formula stored which does some conversion of data. Lets say this is would be:
#left(fieldname;2)
If the fieldname contained 'hello' this would result in 'he'. Nothing to fancy here. Now I would like to use this in an xpage.
I wrote a function called executeFormula(doc). I call this function from an action on a xpage. This xpage contains 1 notes document datasource. The function call is
executeFormula(datasource.getDocument(true))
Now for some reason the #formula is never calculated correctly. Do I need to save the document first before I can use session.evaluate(kwFormula,doc) or is the #formula wrong in some way?
p.s. I forgot to mention that this code is working inside a customvalidator
Without seeing the code for the executeFormula(doc) function it is very difficult to know exactly how session.evaluate is being called.
I would suggest taking the function out of the equasion for the moment and create a simple test page with the document source and a simple computed field with the session.evaluate in it so that you can see the result. Given your examples above the computed field would be something along the lines of
session.evaluate("#Left(fieldname;2)",xspDoc.getDocument(true));
Once you get acceptable results back then you can move it into your function and verify that it is working there also.
Don't forget that session.evaluate returns a vector so you may beed to do a .getFirstElement() on the returned value if it is not null.
If you're using it in a custom validator, the values posted from the browser/client haven't updated the data model (in your case, the document) yet. This happens after validation is successful.
I imagine it might work for some fields (e.g. fields that are updated after a successful refresh, or stored fields in an existing document).
Actually no need of mentioning the document, eg:- session.evaluate("#username") is enough.
For yours session.evaluate("#left('hello';2)") will work.,

Restore one fetched entity out of many -- Core Data

This question covncerns my lack of understanding of how to use the core data undo manager and how to restore a NSManagedObject to its state before editing was done.
I am just learning my way around Core Data. I have my NSManagedObject classes set up with their dynamic accessors. I perform a fetch that returns several NSManagedObject entity results. Content from each of these entity results (first name, last name) get put into a table view, and then the user picks one out of the table for detailed view and then editing.
The detail view controller receives a pointer to the selected NSManagedObject entity. As the user edits the fields, the corresponding property value in the NSManagedObject entity is updated. This seemed like the cleanest way to manage these changes.
Now, rather than committing the changes using save, I want to provide a cancel-editing feature that rolls back to what is in the data base for that entity. I really only want to restore the one entity and not perform the entire refetch.
I tried rollback and I tried NSUndoManager (with beginUndoGrouping and endUndoGrouping), and that is not working. I don't think I understand what rollback is really supposed to do.
But in any case, I still want to restore the property values in just that single entity (taking the lazy approach to only fetch what is needed, which is the one entity) so that my detail view controller can refill its view with the correct information. Right now it is using the NSManagedObject entity values, which contain the edited values, which were cancelled.
I suppose I could just start the edit process by creating a copy of the NSManagedObject. If the cancel-editing button is pressed, I could copy it back into the original. (I might even be able to just replace the original with the copy by moving the pointer. But since the pointer has actually been passed through several objects, I'm not sure how to manage the retain number on the copy.)
Does anyone have any other suggestions?
Thanks
Using rollback should accomplish what you want and I'm not sure what it doesn't. It is probably an implementation detail error.
You can find the specific managed object/s that were updated but not yet saved by calling the context's updatedObjects.

JSF how to temporary disable validators to save draft

I have a pretty complex form with lots of inputs and validators. For the user it takes pretty long time (even over an hour) to complete that, so they would like to be able to save the draft data, even if it violates rules like mandatory fields being not typed in.
I believe this problem is common to many web applications, but can't find any well recognised pattern how this should be implemented. Can you please advise how to achieve that?
For now I can see the following options:
use of immediate=true on "Save draft" button doesn't work, as the UI data would not be stored on the bean, so I wouldn't be able to access it. Technically I could find the data in UI component tree, but traversing that doesn't seem to be a good idea.
remove all the fields validation from the page and validate the data programmaticaly in the action listener defined for the form. Again, not a good idea, form is really complex, there are plenty of fields so validation implemented this way would be very messy.
implement my own validators, that would be controlled by some request attribute, which would be set for standard form submission (with full validation expected) and would be unset for "save as draft" submission (when validation should be skipped). Again, not a good solution, I would need to provide my own wrappers for all validators I am using.
But as you see no one is really reasonable. Is there really no simple solution to the problem?
It's indeed not that easy. Validation is pretty tight coupled in JSF lifecycle.
I would personally go for option 1. True, dirty work, but you can just hide that away in an utility class or so. Just grab the <h:form> in question from the viewroot, iterate over its children recursively, hereby testing if component instanceof EditableValueHolder is true, store the found id-value pair in sort of Map and finally persist it.
As a fourth alternative, you could save all the data independently using ajaxical powers. jQuery is helpful in this.
$.post('/savedraft', $('#formid').serialize());
It only requires Javascript support at the client side.
Update: the JSF utility library OmniFaces has a <o:ignoreValidationFailed> taghandler for the exact purpose. It was indeed not a simple solution as it requires a custom <h:form> as well. It does its job by providing a custom FacesContext instance during the validations and update model values phases which does a NOOP in the validationFailed() and renderResponse() methods. So the components are still invalidated and the messages are still attached, but it would still proceed to the update model values and invoke application phases.
I had the same problem and I didn't like the idea of skipping all the validations. After a lot of thought I ended up wanting only to skip required fields validation. The logic behind this is the user either complete a field correctly or doesn't complete it at all. This is very important for me because everything ends up in the database and, of course, I don't want to overflow a database field or end up saving a String value into an INT database field for instance.
In my experience, skipping required fields allows enough margin of manoeuvre to save a draft. To achieve that I ended up writing a requiredWarnValidator that shows up a single warn message.
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
if (value == null) {
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_WARN);
message.setSummary("This field is required.");
context.addMessage(component.getClientId(), message);
context.validationFailed();
}
}
In this validator I do not throw a ValidatorException() because I want to pass the validation phase but I call validationFailed() because I want to know if a required field is not filled.
I have a flag (completed) in the entity I use to save my form. When saving the form, I check isValidationFailed().
if true at least one required field is not filled : I uncheck the flag completed. (it is a draft)
if false all the form is completed : I check the flag completed. (it is not a draft)
This also allows me to have a single "Save" button instead of two buttons ("Save" and "Save as a draft").
Notes and known pitfalls :
If you are saving your draft to the database then you have to make sure there are no NOT NULL constraints.
When using converters and validators you have to make sure they can handle NULL values.
You will lose the required field asterisk in the outputLabel for your fields.

Resources