Class Carro {
String name
String marca
String matricula
}
Class CarroMovel{
String pro1
String prop2
String prop3
Carro carro
static hasMany = [ carros: Carro]
}
def save2 = {
def carroInstance = new Carro()
def carroMovelInstance = new CarroMovel()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula
carroMovelInstance.prop1 = params.carroMovel.prop1
carroMovelInstance.prop2 = params.carroMovel.prop2
carroMovelInstance.prop3 = params.carroMovel.prop3
carroInstance.save()
carroMovelInstance.carro = carroInstance
carroMovelInstance.save()
}
The CarroInstance is saving, but the carroMovelInstance isn't. I cannot figure it out. Any help would be apreciated.
Grooveek is correct in that you haven't ever invoked carroMovelInstance.save().
However, it might be simpler for you to simply take advantage of Grails' databinding, instead of unnecessarily creating the associations and manually binding the parameters.
// Update your Carro domain.
def Carro {
String name
String marca
String matricula
// will cause persistence operations to cascade from CarroMovel to Carro
static belongsTo = CarroMovel
}
// Update your save2 action.
// By passing 'params' to the CarroMovel constructor, Grails will bind request
// parameters to domain properties of the same name; it even works with associations!
def save2 = {
def carroMovelInstance = new CarroMovel(params)
if(carroMovelInstance.validate) {
carroMovelInstance.save()
}
}
Read up on Grails Data Binding, particularly the parts about associations. Additionally, read "Understanding Cascading Updates and Deletes" to understand how a call to save() on a parent domain object will (or will not) cascade to an associated domain object.
you never ask for the carroMovelInstance to save... The carro instance has nor reference to carroMovel instance so there is no cascading of saving
Related
I am trying to query for a list of ids of type Long in GAE/JDO. And I'm getting the following exception when I call detachCopyAll() on the result set.
org.datanucleus.jdo.exceptions.ClassNotPersistenceCapableException: The class "The class "java.lang.Long" is not persistable. This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data/annotations for the class are not found." is not persistable. This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data for the class is not found.
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:241)
at org.datanucleus.jdo.JDOPersistenceManager.jdoDetachCopy(JDOPersistenceManager.java:1110)
at org.datanucleus.jdo.JDOPersistenceManager.detachCopyAll(JDOPersistenceManager.java:1183)
...
I can query for a list of User objects and detach them just fine. I expected all primitive wrapper classes like Long to be persistable. What am I doing wrong? Below is the code I'm working with.
#PersistenceCapable(identityType=IdentityType.APPLICATION, detachable="true")
public class User
{
#PrimaryKey
#Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
private Long id;
private String email;
}
#SuppressWarnings("unchecked")
public static List<Long> getUserKeys(String email)
{
assert email != null;
List<Long> keyList = null;
PersistenceManager pm = null;
Query query = null;
try {
pm = PMF.get().getPersistenceManager();
query = pm.newQuery("select id from " + User.class.getName());
query.declareParameters("String emailParam");
query.setFilter("email == emailParam");
List<Long> resultList = (List<Long>) query.execute(email);
// next line causes the ClassNotPersistenceCapableException
keyList = (List<Long>) pm.detachCopyAll(resultList);
}
finally {
if (query != null) query.closeAll();
if (pm != null) pm.close();
}
return keyList;
}
List<Long> resultList = (List<Long>) query.execute(email);
// next line causes the ClassNotPersistenceCapableException
keyList = (List<Long>) pm.detachCopyAll(resultList);
I don't understand what you are doing here. A List<Long> does not have to be detached. You'd want to detach instances of your User entity class, but a Long is a Long, and you can just do whatever you need to do with the resultList.
The error message is confusing, but just caused by Long not being an entity class.
The Goal is to have a list of options (that a user can chose through radio buttons) in one place(for eg: a yaml config file). No other place should have this list hard-coded
I've done something similar to create select elements, and I think enums worked just fine. Doing radio buttons should be very similar. I've set it up so that the labels can be defined in the messages file. I'm going to try to excerpt the relevant portions from my larger auto-form-generation code (using FastTags) the best I can. It's a bit heavy for this one case but it makes sense in the larger system.
I use the tag like #{form.selector 'order.status' /}, which looks find the variable named order in the template, sees that status is declared as public Status status, and then goes to find all the values of the Status enum and generate options for them in the select element.
First, I use a FieldContext object which just contains a bunch of info that's used by the other code to determine what to generate along with some utility methods:
public class FieldContext {
public final Map<?,?> args;
public final ExecutableTemplate template;
public final int fromLine;
public Class clazz = null;
public Field field = null;
public Object object = null;
public Object value = null;
private Map<String,String> attrs = new HashMap<String,String>();
private Map<String,Boolean> printed = new HashMap<String,Boolean>();
private List<Option> options;
...
Then I have this in another helper class (its info gets added to the FieldContext):
public List<Option> determineOptions(FieldContext context) {
List<Option> options = new ArrayList<Option>();
if (context.field.getType().isEnum()) {
for (Object option : context.field.getType().getEnumConstants()) {
options.add(new Option(option.toString(), Message.get(option.toString())));
}
}
return options;
}
then the tag declaration is
public static void _selector(Map<?,?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) {
String field_name = args.get("arg").toString();
TagContext.current().data.put("name", field_name);
SelectHelper helper = HelperFactory.getHelper(SelectHelper.class);
try {
FieldContext context = new FieldContext(field_name, args, template, fromLine);
helper.autoconfigure(context);
TagContext.current().data.put("selected", helper.determineValue(context));
out.print("<div class=\"formutil-field formutil-selector\">");
out.print("<label for=\"" + context.getAttr("id") + "\">");
out.print(helper.findOrCreateLabel(context));
out.print("</label>");
out.print("<select");
context.printAttribute(out, "id", "name");
out.print(">");
if (context.hasOptions()) {
for (Option option : context.getOptions()) {
out.print("<option value=\"" + option.value + "\">" + option.label + "</option>");
}
}
out.print("</select>");
context.printErrorIfPresent(out);
context.printValidationHints(out);
out.println("</div>");
}
...
}
I am trying to pass a variable from a method in my Controller to a method in a Model. Since the method in the Model takes one argument (which was designed earlier), I cannot pass my variable as an argument to the method in the Model. And also, the method in this Model is called by other controllers too, so if I change the argument, I have to change all the controllers too, which would be a tedious task.
What I have been trying so far is- I created one MyVariableClass and declared a property. Then I instantiated that class and set the property string to the variable that I wanted to pass. Now, in my Model's method, I instantiated the same MyVariableClass again, but when I did that, the value of the variable was set to null. The code I have right now is -
public ActionResult ItemInformation( string id)
{
//Pass a string to MyVariable
MyVariableVClass params = new MyVariableClass();
params.myVariable = "abc";
//This is what My Model is taking as an argument(id), and I don't want to
//pass mYvariable along with that argument because it will break other controllers
// too which calls this method
var itemInformation = _repository.GetItemInformation(id);
return View(itemInformation);
}
and MyVariableClass
public class MyVariableClass
{
public string myVariable { get; set; }
}
and the method in My Model
public IList<Items> GetItemInformation(string itemId)
{
MyVariableClass webType = new MyVariableClass();
var _params = webType.myVariable;
//Check this variable and perform database query
if (_params =="this")
{
var query = myFirstQuery;
}
else
{
var query = mySecondQuery;
}
//return ....
}
Anybody has solution to this? Thanks in Advance!
Any reason why subclassing your model and overriding the GetItemInformation method wouldn't work? Or, even easier, why not just overload the GetItemInformation method with one that takes two strings? Your other controllers can still use the one that only takes a single string.
public IList<Items> GetItemInformation(string itemId, MyVariableClass webType)
{
var _params = webType.myVariable;
//Check this variable and perform database query
if (_params == "this")
{
var query = myFirstQuery;
}
else
{
var query = mySecondQuery;
}
//return ....
}
public IList<Items> GetItemInformation(string itemId)
{
MyVariableClass fauxType = new MyVariableClass();
fauxType.myVariable = "not this";
return GetItemInformation(itemId, fauxType);
}
Try using session variable.
I have a bunch of variables in a class. There are situations when I want to set then to null/ "temp" etc as per a well defined logic. The challenge is to list out the variables at multiple places- tedious and error-prone.
classname.speed=NaN
classname.speedtype="not_set"
classname.distance=NaN
classname.distancetype="not_set"
Ideally, would prefer a way to refer to these variables programatically and set something like
"for all class variables- if variable ends in type, set as "not_set"; for other variables set as NaN
How can I achieve this? Any pointers will help
The simplest approach would be just write function to clear them all.
If you want something more automatic, it will requre efforts - look at introspection api. Basically, you call describeType on your class and it returns XML description. All variables will be listed there, along with other info. Then you can parse returned XML and set all variables to needed value, accessing them dynamically with square bracket syntax:
var myClass:MyClass = new MyClass();
myClass["varName"] = "new value";
It can be achieved through Inheritance i.e. implementing interface or extending class
which contains common fields
public class MyClass
{
public a:String = null;
public b:String = null;
public function MyClass()
{
}
}
which contains common var and Child Class could be
public class MyClassChild extends MyClass
{
public var c:String = null;
public function MyClassChild()
{
super();
this.a ="";
this.b ="";
}
}
and you can cast or use for each loop to set values
var temp:MyClassChild = new MyClassChild ();
MyClass(temp).a = "Hello World";
Hopes that helps
Can I convert a IQueryable result to a injected object on the fly?
I know I can do this with the help of Valueinjecter:
usercategory uc1 = new usercategory(example);
usercategoryViewData ucVD1 = new usercategoryViewData();
ucVD1.injectFrom(uc1);
So instead of this:
from u in db.usercategories
where u.id==id
select new usercategoryViewModel {id = u.id, name = u.id, description = u.id};
I would like to use something like:
from u in db.usercategories
where u.id==id
select new usercategoryViewModel.InjectFrom(u);
The other alternative I have atm is to loop through a IEnumerable and create one with injected objects instead.
here I show 2 ways of doing this:
public class Foo
{
public string Name { get; set; }
}
[Test]
public void TestMethod1()
{
var bars = new[] { new { Name = "aaa" }, new { Name = "bbb" } };
IEnumerable<Foo> foos = bars.Select(o => new Foo().InjectFrom(o)).Cast<Foo>();
IEnumerable<Foo> foos2 = from bar in bars
select new Foo().InjectFrom(bar) as Foo;
Assert.AreEqual(bars.First().Name, foos.First().Name);
Assert.AreEqual(bars.First().Name, foos2.First().Name);
}
Whilst that might be possible, if there's any complexity in u then I think it's a bad idea.
At some point the ORM you're using (Linq-to-SQL? EF?) needs to switch from executing on the database to executing in .NET. At that boundary it needs to work out what data it needs from the database. In the first example, that's completely clear: it only needs u.id. In the second it has no idea: it doesn't know what properties InjectFrom will read from it, so it will need to load all the values from the UserCategories table, and maybe related objects too, just in case.