JPA Error a relationship that was not marked cascade PERSIST - jsf-2

I have a table and JPA Entity called State (of a Country) and through JPA, I am trying to write a code for a User (Entity) to register on the website. Clearly, there is a one-to-one relationship between User and State (a User belongs to only one State). Here is my code:
#Entity
#Table(name = "STATE")
public class State implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
private int id;
#Column(name = "CODE")
private String code;
#Column(name="NAME")
private String name;
And User code is as follows:
#Entity
#Table(name = "USER")
public class User implements Serializable {
....
#OneToOne()
#JoinColumn(name = "STATE_ID", referencedColumnName = "ID")
private State state;
The database tables are as follows:
CREATE TABLE IF NOT EXISTS `bjm`.`STATE` (
`CODE` CHAR(2) NOT NULL,
`NAME` VARCHAR(40) NOT NULL,
`POST_CODE_PREFIX` VARCHAR(10) NULL,
`LANG` CHAR(2) NOT NULL,
`ID` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ID`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `bjm`.`USER` (
`ID` INT NOT NULL AUTO_INCREMENT,
`FIRSTNAME` VARCHAR(45) NOT NULL,
`LASTNAME` VARCHAR(45) NOT NULL,
`EMAIL` VARCHAR(50) NOT NULL,
....
PRIMARY KEY (`ID`),
CONSTRAINT `fk_USER_STATE1`
FOREIGN KEY (`STATE_ID`)
REFERENCES `bjm`.`STATE` (`ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
)
ENGINE = InnoDB;
However, when I try to create/register User in my JSF2 application, I get the following error:
java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: org.bjm.model.State
I don't want to create a new State record in the DB. They are already there (as reference data) and just need an assignment to the User via the foreign key.
May be I a missing something, but I need a resolution. Any constructive comment would be of extreme help.
Thanks

Clearly, there is a one-to-one relationship between User and State (a User belongs to only one State)
Well, clearly this is wrong. This is classic #ManyToOne, because many users are from the same state. It should look like this:
#Entity
#Table
public class User implements Serializable {
// (...)
#ManyToOne
#JoinColumn(name = "STATE_ID")
private State state;

Related

How spring data jpa mapped split a table?

How spring data JPA mapped split a table?
Already, I have an Entity class:
#Entity
#Table(name = "tbl_attendance_teacher_result")
#Data
public class AttendanceRecord extends TimeEntity {
#EmbeddedId
private AttendanceRecordPrimaryKey id;
private int gid;
private String teacherName;
}
but now I want to split the table tbl_attendance_teacher_result by gid;
table name like
tbl_attendance_teacher_result_1,
tbl_attendance_teacher_result_2 ...etc.
How should I modify the entity class?

Can't create relationship OneToMany

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?

AspNetUserRoles Table is not populated using Entity Framework Database First in MVC 5

In my project I am trying to retrieve all the users and their roles in MVC 5 using Entity Framework.
The DBContext is set up using Database first. But it is wearied that the AspNetUserRoles Table is not populated automatically and the relationship between AspNetUser and AspNetRole is many-to-many.
Below is the link to the screenshot.
Can anyone give me some hints on this? Many thanks.
If you want to manage the AspNetUsersRoles, you must make the following modification.
Remove the primary key, actually is conformed by UserId and RoleId
Add a new Id field in the table and check like primary key.
Update your model.
Now you can scaffolding this entity and create the controller and the view for manage this.
Note: Remember that by changing the primary key of this table on the DB side means you have to control how AspNetUserRoles records are created on the Application Side, considering you now could have record redundancy on the table, for instance:
MyRoles=1 (PK), UserID=1, RoleID=1, Comment= User1 is Admin
MyRoles=2 (PK), UserID=1, RoleID=2, Comment= User1 is Admin again
Which means the same, so manage this logic upon AspNetUserRoles creation!
I assume that there is no problem that you cannot see AspNetUserRoles table under EDMX at all.
You have access to this table via code and in most cases is enough.
Normally under ASP.NET MVC 5 you have something like
public class AccountController : Controller
{
private ApplicationUserManager _userManager;
...
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
...
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
So under Login method you can get user roles like this
[System.Web.Mvc.HttpPost]
[System.Web.Mvc.AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
...
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, false, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
{
ApplicationUser user = UserManager.FindByName(model.Email);
var roles = (AppUserRoles[])Enum.GetValues(typeof(AppUserRoles));
foreach (var role in roles)
{
if (UserManager.IsInRole(user.Id, role.ToString()) && role == AppUserRoles.Administrators)
{
// Do what you need here
// logger.Info("Login attempt is success.");
return RedirectToAction("Index", "Admin");
}
You need also to have this enum in your code
public enum AppUserRoles
{
Administrators = 1,
Managers = 2,
Users = 3,
Others = 4
}
Another approach is to use STORED PROCEDURE that you can use in EDMX.
CREATE PROCEDURE GetUserRoleByUserId
#UserId nvarchar(128)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT [UserId],[RoleId] FROM [AspNetUserRoles] WHERE [UserId] LIKE #UserId
END
GO
Hope this will help you.
Because the roles are not seeded by default until you explicitly add them in your seed method
Read about Asp.Net Identity modules
http://www.asp.net/identity
http://www.codeproject.com/Articles/762428/ASP-NET-MVC-and-Identity-Understanding-the-Basics

Invalid column name while updating table, split entity

When i try to SaveChanges() to insert a new entity, I get the following exception.
System.Data.Entity.Infrastructure.DbUpdateException : An error occurred while updating the entries. See the inner exception for details.
----> System.Data.UpdateException : An error occurred while updating the entries. See the inner exception for details.
----> System.Data.SqlClient.SqlException : Invalid column name 'LD_Content'.
Invalid column name 'LD_File'.
I'm not using Code First nor Database First approach here. The database is preexisting, but the entity code is generated from custom templates.
These are the DB tables:
CREATE TABLE [dbo].[Licences](
[L_ID] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Licences] PRIMARY KEY NONCLUSTERED
(
[L_ID] ASC
))
GO
ALTER TABLE [dbo].[Licences] WITH CHECK ADD CONSTRAINT [FK_Licences_LicenceData] FOREIGN KEY([L_ID])
REFERENCES [dbo].[LicenceData] ([LD_ID])
GO
CREATE TABLE [dbo].[LicenceData](
[LD_ID] [uniqueidentifier] NOT NULL,
[LD_Content] [varbinary](max) NOT NULL,
[LD_File] [varbinary](max) NULL,
CONSTRAINT [PK_LicenceData] PRIMARY KEY NONCLUSTERED
(
[LD_ID] ASC
))
These are the entities:
[Table("Licences")]
public class Licence
{
[Required, Display(Name="ID"), Column("L_ID")]
public Guid ID { get; set; }
public virtual LicenceFile File { get; set; }
[Required, Display(Name = "Content"), Column("LD_Content")]
public virtual string Content { get; set; }
}
[Table("LicenceData")]
public class LicenceFile
{
[Required, Display(Name = "ID"), Column("LD_ID")]
public Guid ID { get; set; }
[Display(Name = "File"), Column("LD_File")]
public byte[] File { get; set; }
}
And this is the mapping:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Licence>()
.Map(m =>
{
m.Properties(licence => new {licence.Content});
m.ToTable("LicenceData");
});
modelBuilder.Entity<Licence>().HasRequired(i => i.File).WithRequiredPrincipal();
base.OnModelCreating(modelBuilder);
}
The entity is created with its navigation property set:
new Licence
{
Content = "content",
File = new LicenceFile()
}
Summing up, there are two tables in one-to-one relationship. One of the entities, Licence, maps to its table (Licences) and also to one of the columns of the other table (entity splitting). The second entity, LicenceFile, maps to the ramaining columns of the other table (LienceData).
What has gone wrong here?

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