Can't create relationship OneToMany - entity-relationship

I have below code:
Entity User:
#Entity
#Table(name="USERS")
public class User extends AbstractModel{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="USER_ID")
private long userId;
#OneToMany(mappedBy="createdBy", fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
private Set<Address> loans = new HashSet<Address>();'
Entity Address:
#Entity
#Table(name = "ADDRESS")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ADDRESS_ID")
private long addressId;
#ManyToOne(cascade=CascadeType.PERSIST)
#JoinColumn(name="USER_ID")
private User createdBy;
And there is a problem because when I want to try save User into database I dont have an Entry for Address(in DB of course).
I would like to create an automatic Address entry creation when User is saved...
Maybe someone had this kind of problem and coult help...

I think name of joinColumn should be USER_ID.
Could you try?

Related

How to cache and get properties from extended Identity, AspUser in ASP Identity 2.2

To support tenan/companies, I added/extended a new property to the AspUser Table called OrgId in ASP MVC 5, Identity 2.2 role management, I added the corresponding OrgId to some other tables, looked here but no answers
During User Login() and the UserSession
how do I cache, configure & retrieve the OrgId, so that I can perform DBConext filtering/CRUD of table for Org specific records?
Advice: is better to save this in the Claims, FormsToken or Session - and
how to set the tenanId context in session?
I know how to get user, but not the extended Org
ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
Your customized user class should be like this:
public class CustomizedUser : IdentityUser
{
public int OrgId {get; set;}
public DateTime JoinDate { get; set; }
//...
// and other simple fields
//Fields related to other tables
public virtual ICollection<Article> Articles { get; set; } = new List<Article>();
//...
}
And your CustomizedApplicationDbContext class
public class CustomizedApplicationDbContext : IdentityDbContext<CustomizedUser>, IApplicationDbContext
{
public CustomizedApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static CustomizedApplicationDbContext Create()
{
return new CustomizedApplicationDbContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//your entity configurations go here if you have any
base.OnModelCreating(modelBuilder);
}
//These fields are neccessary in order to maintain the power of base class
public DbChangeTracker Changetracker => base.ChangeTracker;
public Database DatabBase => base.Database;
//your own dbsets go here except CustomizedUser, because the base class IdentityDbContext<CustomizedUser> handles it
public IDbSet<Article> Articles { get; set; }
//...
}
Now, Remember to replace every ApplicationDbContext references with CustomizedApplicationDbContext and every IdentityUser refrences with CustomizedUser in your code (specially in your ManageController created by mvc).
From now on, you can easily access users table just like other tables:
var db = new CustomizedApplicationDbContext();
var user = db.CustomizedUsers.First(x=> x.OrgId == 10 || Email == "sth#yahoo.com");
And to get the current user OrgId, you can use something like this(without querying db):
var currentUserOrgId = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(User.Identity.GetUserId()).OrgId;
Hope this was helpful
You can get the current user in ASP.NET Identity as shown below:
ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext()
.GetUserManager<ApplicationUserManager>()
.FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
//If you use int instead of string for primary key, use this:
ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext()
.GetUserManager<ApplicationUserManager>()
.FindById(Convert.ToInt32(System.Web.HttpContext.Current.User.Identity.GetUserId()));
For getting custom properties from AspNetUsers table:
ApplicationUser user = UserManager.FindByName(userName);
string name = user.Name;
Hope this helps...

Selecting Data directly vs using navigation property in EF

Hi there in a MVC application I have the following sample POCO classes(Actual application has 10-15 screens for employee data). Manager has many employees and he can update their personal and contact details. I am considering 3 approaches to retrieve the current employee data from database using EF.
1) When manager select an employee, store EmployeeId in Session (Session["currentEmp"]) and use this EmployeeId to get the data for the current employee.
like:
int employeeId = (int)Session["currentEmp"];
EmployeeContactDetails1 empCtDet1 = ctx.EmployeeContactDetails1.Find(employeeId);
then
EmployeeContactDetails2 empCtDet2 = ctx.EmployeeContactDetails2.Find(employeeId);
2) Have a discriminator property such as "unlocked" on Employee class and when manager select the employee then mark it unlocked = true and update the column in database and the do something like this for further data retrieval
EmployeeContactDetails1 empCtDet1 = ctx.Employees.Where(e => e.unlocked == true).EmployeeContactDetails1;
EmployeeContactDetails2 empCtDet2 = ctx.Employees.Where(e => e.unlocked == true).EmployeeContactDetails2;
3) Or
EmployeeContactDetails1 empCtDet1 = ctx.EmployeeContactDetails1.Where(e => e.Employee.unlocked == true).FirstOrDefault();
EmployeeContactDetails2 empCtDet2 = ctx.EmployeeContactDetails2.Where(e => e.Employee.unlocked == true).FirstOrDefault();
I would like to ask you which one is better keeping in mind security and performance.
public class Manager{
public int ManagerId{get;set;}
public string ManagerName{get;set;}
public string someMoreProp{get;set;}
public ICollection<Employee>Employee{get;set;}
}
public class Employee{
public int EmployeeId{get;set;}
public virtual EmployeePersonalDetails EmployeePersonalDetails{get;set;}
public virtual EmployeeContactDetails EmployeeContactDetails{get;set;}
public int ManagerId{get;set;}
public virtual Manager Manager{get;set;}
}
public class EmployeePersonalDetails{
public int EmployeeId{get;set;}
public string Name{get;set;}
public string Age{get;set;}
public Address AddressOne{get;set;}
public Employee Employee{get;set;}
}
public class EmployeeContactDetails1{
public int EmployeeId{get;set;}
public string Line1{get;set;}
public string Line2{get;set;}
public Employee Employee{get;set;}
}
public class EmployeeContactDetails2{
public int EmployeeId{get;set;}
public string Line1{get;set;}
public string Line2{get;set;}
public Employee Employee{get;set;}
}
public class EmployeeContactDetails3{
public int EmployeeId{get;set;}
public string Line1{get;set;}
public string Line2{get;set;}
public Employee Employee{get;set;}
}
public class EmployeeContactDetails4{
public int EmployeeId{get;set;}
public string Line1{get;set;}
public string Line2{get;set;}
public Employee Employee{get;set;}
}
First, don't use Session. The mentioned way you're considering is a completely unacceptable use of sessions. A well-designed web app will as much as feasibly possible avoid sessions like the plague. The notable exception is of course authentication, which can't be achieved in a user-friendly way by any other means.
Second, in general, you seem to be making this far too complicated. It's not entirely clear what you're trying to achieve, but it sounds like you simply want the manager to be able to do something like click on an employee and then be taken to a view where they can edit that employee's details. The correct way to do that is to have a dedicated URI, consisting of the employee id or some other uniquely identifying token. For example:
/employees/{id}/edit
Then, in the action that that URI routes to, you would use the id param to look up the employee:
var employee = db.Employees.Find(id);
if (employee == null)
{
return new HttpNotFoundResult();
}
Since, presumably, you would only want the manager of that employee to be able to edit the employee, you would simply do object-level authorization by including the manager's id in the query:
var managerId = User.Identity.GetUserId(); // currently logged in manager
var employee = db.Employees.SingleOrDefault(m => m.EmployeeId == id && m.ManagerId == managerId);

Create dynamic finder between two classes in Grails

I have two domain classes (db tables) in my Grails project:
class Doctor {
String role;
String name;
String surname;
String address;
...
#NotNull
static belongsTo = [secUser:SecUser]
....
}
class SecUser {
transient springSecurityService
String username
String password
...
}
I would like to find all SecUser that have not a correspondent Doctor.
How can I do it?
I think you need something like this:
SecUser.executeQuery(" FROM SecUser secUser WHERE NOT EXISTS (SELECT doctor.SecUser FROM Doctor doctor")

how to get parents id while fetching child's information - Grails?

How to access firstname and lastname of user depending on which statusItem is displayed which is the child of the user.
class UserAccount implements Serializable {
static transients = ['pass','passConfirm','familyPicTmp', 'familyPicTmpFilename', 'photoTmp', 'photoTmpFilename']
static hasMany = [authorities: Authorisation, memberships:FamilyMembership, progenitorIwi:Family, politicItems:PoliticItem,
relationships:Relationship, , agents:UserAccount, media:UserMedia, status:Status]
static mappedBy = [ progenitorIwi:"progenitor",relationships:'relationTo', relationships:'userAccount']
static fetchMode = [memberships:FetchMode.JOIN, agents:FetchMode.JOIN]
static mapping = {
memberships(lazy:false)
agents(lazy:false)
}
static belongsTo = [Authorisation]
STATUS DOMAIN
class Status {
static belongsTo = [userAccount:UserAccount]
def String statusMessage
Date dateCreated
Date lastUpdated
def String statusType
POLITIC DOMAIN
class PoliticItem {
SystemEntity politicItemName
UserAccount userAccount
def String politicItemValue
def boolean shared = false
Date dateCreated
Date lastUpdated
How can we load all the users that belong to all the status on to the politic's views?
I am still not sure which part you dont know. Assuming userAccount has the firstName and lastName field to access them from status try this:
status is the instance of your Status class. The one you need to get the userAccount off of it.
status.userAccount.firstName
or
status.userAccount.lastName

Grails many to many relationship migration

Hello I have two domain classes as following
class Users {
String password
String firstName
String lastName
String emailAddress
String username
Company company
.....
static hasMany = [projects:Projects];
}
Another class
class Projects {
String projectName
String description
Users projectLead
Date dateCreated
Date lastUpdated
static belongsTo = Users
}
These classes obviously has one to many relationship but now I want to change it to many to many relationship by adding "ProjectMembership" class but the problem I have is that my application has already gone into production and there are people who are already using the app. In such a case they already have one user->many projects in the the db. In such a case how can I migrate this existing data and change my prod app to have m2m relationship which will looks like following.
class Users {
String password
String firstName
String lastName
String emailAddress
String username
Company company
.....
static hasMany = [projectMemberships:ProjectMemberships];
}
Another class
class Projects {
String projectName
String description
Users projectLead
Date dateCreated
Date lastUpdated
static hasMany = [projectMemberships:ProjectMemberships];
}
and
class ProjectMemberships{
Users u
Projects p
}
This is best done with a migration tool like Liquibase, and the http://grails.org/plugin/database-migration plugin is probably your best be in Grails since it uses Liquibase and is tightly integrated with GORM. But this one's easy enough to do by hand.
I wouldn't use hasMany since you can easily manage everything from the ProjectMemberships class, so your Users and Projects classes would be
class Users {
String password
String firstName
String lastName
String emailAddress
String username
Company company
.....
}
and
class Projects {
String projectName
String description
Date dateCreated
Date lastUpdated
}
I'd go with a ProjectMemberships class that uses a composite key, which requires that it implement Serializable and have a good hashCode and equals:
import org.apache.commons.lang.builder.HashCodeBuilder
class ProjectMemberships implements Serializable {
Users u
Projects p
boolean equals(other) {
if (!(other instanceof ProjectMemberships)) {
return false
}
other.u?.id == u?.id && other.p?.id == p?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (u) builder.append(u.id)
if (p) builder.append(p.id)
builder.toHashCode()
}
static ProjectMemberships get(long userId, long projectId) {
find 'from ProjectMemberships where u.id=:userId and p.id=:projectId',
[userId: userId, projectId: projectId]
}
static ProjectMemberships create(Users u, Projects p, boolean flush = false) {
new ProjectMemberships(u: u, p: p).save(flush: flush, insert: true)
}
static boolean remove(Users u, Projects p, boolean flush = false) {
ProjectMemberships instance = ProjectMemberships.findByUsersAndProjects(u, p)
if (!instance) {
return false
}
instance.delete(flush: flush)
true
}
static void removeAll(Users u) {
executeUpdate 'DELETE FROM ProjectMemberships WHERE u=:u', [u: u]
}
static void removeAll(Projects p) {
executeUpdate 'DELETE FROM ProjectMemberships WHERE p=:p', [p: p]
}
static mapping = {
id composite: ['p', 'u']
version false
}
}
Use ProjectMemberships.create() to add a relationship between a user and a project, and ProjectMemberships.remove() to remove it.
Run grails schema-export to see the updated DDL (it'll be in target/ddl.sql). Run the create table statement for the project_memberships table, e.g.
create table project_memberships (
p_id bigint not null,
u_id bigint not null,
primary key (p_id, u_id)
)
Then populate it with this SQL (depending on your database you might need a slightly different syntax):
insert into project_memberships(p_id, u_id) select id, project_lead_id from projects
and finally drop the project_lead_id column from the projects table.
Of course do a database backup before making any changes.
You can get a user's projects with
def projects = ProjectMemberships.findAllByUsers(user)*.p
and similarly a project's users with
def users = ProjectMemberships.findAllByProjects(project)*.u

Resources