-
Type:
Bug
-
Status: Resolved
-
Priority:
Major
-
Resolution: Complete
-
Affects Version/s: 1.1.3.RELEASE
-
Fix Version/s: 1.1.4.RELEASE
-
Component/s: PERSISTENCE
-
Labels:None
When having a @ManyToOne field with GOOGLE_APP_ENGINE, Spring ROO generates code that never sets the field and re-fetches it every time it is accessed:
// Spring Roo 1.1.4.BUILD-SNAPSHOT [rev c6e48eb] log opened at 2011-04-15 18:13:20 project --topLevelPackage com.test persistence setup --provider DATANUCLEUS --database GOOGLE_APP_ENGINE entity --class ~.User --serializable --permitReservedWords field string --fieldName name --notNull json all controller scaffold --class ~.web.UserController --entity ~.User entity --class ~.UserRole --serializable field string --fieldName name --notNull field reference --fieldName user --type ~.User --cardinality MANY_TO_ONE --permitReservedWords controller scaffold --class ~.web.UserRoleController focus --class ~.User field set --fieldName roles --type ~.UserRole --cardinality ONE_TO_MANY --mappedBy user quit // Spring Roo 1.1.4.BUILD-SNAPSHOT [rev c6e48eb] log closed at 2011-04-15 18:14:49
Generates a UserRole class:
@RooJavaBean @RooToString @RooEntity @RooSerializable public class UserRole { @NotNull private String name; @ManyToOne private User user; }
which generates UserRole_Roo_JavaBean.aj that contains the getter and setter for the User class
public User UserRole.getUser() { if (this.userId != null) { this.user = User.findUser(this.userId); } else { this.user = null; } return this.user; } public void UserRole.setUser(User user) { if (user != null) { if (user.getId () == null) { user.persist(); } this.userId = user.getId(); } else { this.userId = null; } }
HOWEVER, every time role.user is accessed, a query is made. This is very inefficient, especially if you access this property multiple times in a code block.
Suggestion, take advantage of the field you are marking transient and generate the following instead:
public User UserRole.getUser() { if (this.userId != null) { if (this.user == null || this.user.getId() != this.userId) { this.user = User.findUser(this.userId); } } else { this.user = null; } return this.user; } public void UserRole.setUser(User user) { if (user != null) { if (user.getId () == null) { user.persist(); } this.userId = user.getId(); } else { this.userId = null; } this.user = user; }
This way the now marked transient field is utilized and subsequent requests don't result in calls to the database.