I've been through answers on this question here and so far nothing mention applies or has fixed the issue.
Edit
What I've tried:
Updated ContextKey column in __MigrationHistory table.
Copied all my older migrations back from the old version of my project.
Problem
I've just come across an error in my app that was caused by 0 values in a column that's supposed to link 2 tables. As such, I've updated my data model to structure a relationship between them:
public class ContactGroup
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Contact
{
public int Id { get; set; }
public ContactGroup ContactGroup { get; set; }
// other contact columns go here
}
One of the other tables I have is called Campaigns, so now having added a migration that sets up my foreign keys, I want to update-database
Here's where my problem is since I'm getting an error saying:
There is already an object named 'Campaigns' in the database.
I know there's already an object with this name in the database because its one of the objects I'm establishing a relationship to.
Here's the Migration as generated by Entity Framework
public partial class StructuredRelationships : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Campaigns",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Client = c.String(),
EmailAddress = c.String(),
PhoneNumber = c.String(),
FaxNumber = c.String(),
PhysicalAddress = c.String(),
PostalAddress = c.String(),
DateSent = c.DateTime(),
SmtpServerAddress = c.String(),
SmtpServerPort = c.Int(nullable: false),
SmtpServerUser = c.String(),
SmtpServerPassword = c.String(),
Deleted = c.Boolean(nullable: false),
SendInterval = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.ContactGroups",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Deleted = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Contacts",
c => new
{
Id = c.Int(nullable: false, identity: true),
ContactGroupId = c.Int(nullable: false),
CompanyName = c.String(),
Salutation = c.String(),
FirstName = c.String(),
LastName = c.String(),
EmailAddress = c.String(),
Telephone = c.String(),
DirectTel = c.String(),
Mobile = c.String(),
BroadDesignation = c.String(),
Designation = c.String(),
EmployeeCount = c.Int(nullable: false),
EmployeeCountBand = c.String(),
SaTelProvince = c.String(),
SaBroadArea = c.String(),
Town = c.String(),
Suburb = c.String(),
Type = c.String(),
SpecificBusinessClassification = c.String(),
ReferenceNumber = c.String(),
Deleted = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.ContactGroups", t => t.ContactGroupId, cascadeDelete: true)
.Index(t => t.ContactGroupId);
CreateTable(
"dbo.Emails",
c => new
{
Id = c.Int(nullable: false, identity: true),
CampaignId = c.Int(nullable: false),
TemplateId = c.Int(nullable: false),
Sender = c.String(),
From = c.String(),
FromAddress = c.String(),
ReplyTo = c.String(),
ReplyToAddress = c.String(),
Subject = c.String(),
Body = c.String(),
Footer = c.String(),
DateCreated = c.DateTime(nullable: false),
Deleted = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Campaigns", t => t.CampaignId, cascadeDelete: true)
.Index(t => t.CampaignId);
CreateTable(
"dbo.EmailSends",
c => new
{
Id = c.Int(nullable: false, identity: true),
CampaignId = c.Int(nullable: false),
EmailId = c.Int(nullable: false),
ContactGroupId = c.Int(nullable: false),
SendDate = c.DateTime(nullable: false),
TotalRecipients = c.Int(nullable: false),
TotalSent = c.Int(nullable: false),
TotalFailed = c.Int(nullable: false),
Status = c.String(),
CompletedDate = c.DateTime(),
Deleted = c.Boolean(nullable: false),
TrackerUrl = c.String(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Campaigns", t => t.CampaignId, cascadeDelete: true)
.ForeignKey("dbo.ContactGroups", t => t.ContactGroupId, cascadeDelete: true)
.ForeignKey("dbo.Emails", t => t.EmailId, cascadeDelete: true)
.Index(t => t.CampaignId)
.Index(t => t.EmailId)
.Index(t => t.ContactGroupId);
CreateTable(
"dbo.EmailTemplates",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Markup = c.String(),
Deleted = c.Boolean(nullable: false),
})
.PrimaryKey(t => t.Id);
}
public override void Down()
{
DropForeignKey("dbo.EmailSends", "EmailId", "dbo.Emails");
DropForeignKey("dbo.EmailSends", "ContactGroupId", "dbo.ContactGroups");
DropForeignKey("dbo.EmailSends", "CampaignId", "dbo.Campaigns");
DropForeignKey("dbo.Emails", "CampaignId", "dbo.Campaigns");
DropForeignKey("dbo.Contacts", "ContactGroupId", "dbo.ContactGroups");
DropIndex("dbo.EmailSends", new[] { "ContactGroupId" });
DropIndex("dbo.EmailSends", new[] { "EmailId" });
DropIndex("dbo.EmailSends", new[] { "CampaignId" });
DropIndex("dbo.Emails", new[] { "CampaignId" });
DropIndex("dbo.Contacts", new[] { "ContactGroupId" });
DropTable("dbo.EmailTemplates");
DropTable("dbo.EmailSends");
DropTable("dbo.Emails");
DropTable("dbo.Contacts");
DropTable("dbo.ContactGroups");
DropTable("dbo.Campaigns");
}
}
So what's the best way to fix this problem and apply this migration now?
Just remove the CreateTable method targeting dbo.Campaigns from the generated migration. For future migrations this will not be added because the model gets actually serialized in the __MigrationHistory table and it knows that you already took action on it.
This gets recorded on the Model column in __MigrationHistory table and it knows that Campaigns already exists and it will not try to create it again.
Hope this helps
Related
I created a named query that looks like this with a result set mapping:
#NamedNativeQueries({ #NamedNativeQuery(name = "Q_INSTRUMENTS", query = "SELECT i.ID, i.TICKER, i.ISIN, i.SEDOL, i.NAME, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID FROM INSTRUMENT i INNER JOIN COUNTRY c ON i.COUNTRY_ID = c.ID"
+ " GROUP BY i.ID, i.TICKER, i.ISIN, i.SEDOL, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID, c.NAME HAVING i.ID = MAX(i.ID) ORDER BY i.NAME, c.NAME ASC", resultClass = Instrument.class, resultSetMapping = "InstrumentMapping") })
#SqlResultSetMapping(name = "InstrumentMapping", entities = { #EntityResult(entityClass = Instrument.class, fields = {
#FieldResult(name = "id", column = "ID"), #FieldResult(name = "ticker", column = "TICKER"),
#FieldResult(name = "sedol", column = "SEDOL"), #FieldResult(name = "isin", column = "ISIN"),
#FieldResult(name = "name", column = "NAME"), #FieldResult(name = "countryId", column = "COUNTRY_ID"),
#FieldResult(name = "contractSize", column = "CONTRACT_SIZE"),
#FieldResult(name = "expiryDate", column = "EXPIRY_DATE"), #FieldResult(name = "typeId", column = "TYPE_ID") }) })
and here is the class that is annotated with this named query
public class Instrument extends ManagedEntityBase{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(length = 10)
private String ticker;
#Column(length = 30)
private String isin;
#Column(length = 10, unique = true, nullable = false)
private String sedol;
#Column(length = 60, nullable = false)
private String name;
#Column(name = "COUNTRY_ID", nullable = false, insertable = false, updatable = false)
private long countryId;
#Column(name = "TYPE_ID", nullable = false, insertable = false, updatable = false)
private byte typeId;
#Column(name = "CONTRACT_SIZE", nullable = false)
private Long contractSize;
#Transient
private String contractSizeString;
#Temporal(TemporalType.DATE)
#Column(name = "EXPIRY_DATE")
private Date expiryDate;
public Instrument() {
// Default constructor
this.contractSize = 1L;
}
ublic Instrument(String sedol, Country country, InstrumentType type) {
this();
this.sedol = sedol;
this.country = country;
this.type = type;
}
/**
* Creates an {#link Instrument} with the given sedol, isin, country and type.
*
* #param sedol instrument sedol
* #param isin instrument isin
* #param country instrument country
* #param name
* #param ticker
* #param type instrument type
*/
public Instrument(String sedol, String isin, Country country, String name, String ticker, InstrumentType type) {
this(sedol, country, type);
this.isin = isin;
this.name = name;
this.ticker = ticker;
}
}
When I try to call the name query:
public static List<Instrument> getInstruments() {
return DatabaseUtility.getEntityManager().createNamedQuery("Q_INSTRUMENTS").getResultList();
}
I get the following error:
[EL Warning]: 2020-01-31 15:55:40.732--UnitOfWork(1788318093)--Exception [EclipseLink-6044] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.QueryException
Exception Description: The primary key read from the row [ArrayRecord(
=> 3000000002285
=> 00577
=> BMG8827A1045
=> BYX9N24
=> 13 HOLDINGS LTD, THE
=> 2
=> 1
=> null
=> 1)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReadAllQuery(name="Q_INSTRUMENTS" referenceClass=Instrument sql="SELECT i.ID, i.TICKER, i.ISIN, i.SEDOL, i.NAME, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID FROM INSTRUMENT i INNER JOIN COUNTRY c ON i.COUNTRY_ID = c.ID GROUP BY i.ID, i.TICKER, i.ISIN, i.SEDOL, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID, c.NAME HAVING i.ID = MAX(i.ID) ORDER BY i.NAME, c.NAME ASC")
In the table the expiry_date is indeed null but this does not take part from primary key and by default the nullable value is true for expiry date.
I use EclipseLink with PostreSQL.
I try to migrate the current code from old Sybase to new PostreSQL. With Sybase datasource the error does not happen.
I tried using
<property name="eclipselink.jpa.uppercase-column-names" value="true"/>
to make sure the mapping to the columns is not made wrong, but it didn't fix my issue
It seems that my question had its answer in it. The problem was due to wrong mapping for id. The mapping was done using "id" but the column in database is ID (capitalized). That's why I had null for id.
The solution was to put
<property name="eclipselink.jpa.uppercase-column-names" value="true"/>
in the right persistance-unit.
olingo jpa processor v4 Exception when using #ManyToOne relation.
com.sap.olingo.jpa.metadata.core.edm.mapper.exception.ODataJPAModelException: Error when creating Referential Constraints for 'content': Property for 'content_id' not found at 'Repository'
#ManyToOne(optional = true)
#JoinColumn(name = "content_id", insertable = false, updatable = false)
public Repository getContent() {
return content;
}
#ManyToOne
#JoinColumn(name = "space_id", insertable = false, updatable = false)
public Space getSpace() {
return space;
}
I think you need to use refencedColumnName.
refencedColumnName is there to specify another column as the id column of the other table.
#ManyToOne(optional = true)
#JoinColumn(name = "content_id",referencedColumnName="here the id of repository",insertable = false, updatable= false)
Hi I have a relation like this in BookEO and BookAreaEO classes respectively. Now, I wanted to understand what is the purpose of mappedBy and how I can write a query like below in BookEO using JPA
select * from book b where exists (
select book_id from book_report_area ba
where b.book_id = ba.book_id and ba.subject_area_id=200);
// BookEO.java
Set<BookArea> bookAreas;
#Override
#PrivateOwned
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "book", targetEntity = BookAreaEO.class, orphanRemoval = true)
public Set<BookArea> getBookAreas() {
return bookAreas;
}
// BookAreaEO.java
Book book;
#Override
#ManyToOne(fetch = FetchType.LAZY, targetEntity = BookEO.class, optional = false)
#JoinColumn(name = "BOOK_ID", nullable = false)
public Book getBook() {
return book;
}
I have a large DB on MySql Workbench and I'm trying to map the relationship between the entities on Eclipse Mars thanks to Hibernate and the JPA module. The fact is that I receive the error:
"In attribute 'personAddresses', the "mapped by" attribute 'peopleAdd' has an invalid mapping type for this relationship."
This are the entities involved.
1
I've to say that making a forward engineering, Hibernate creating for me an AddressId class, where the composite primary key of Address is mapped. I suspect that the problem could be this, but I'm not certain, can you help me please?
Under I post the code so that it's more clear to understand how the classes are implemented.
#Entity
#IdClass(AddressId.class)
#Table(schema = "YouDroop", name = "Address")
public class Address implements Serializable
{
...
private Collection<Person> peopleAdd = new HashSet<Person>();
#Id
#Column(name = "Address", length = 45, unique = true, nullable = false)
private String address;
#Id
#Column(name = "Number", unique = true, nullable = false)
private int number;
...
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(
name = "PersonHasAddress",
joinColumns = {
#JoinColumn(name = "Address_Address", referencedColumnName = "Address", nullable = false),
#JoinColumn(name = "Address_Number", referencedColumnName = "Number", nullable = false)
},
inverseJoinColumns = {#JoinColumn(name = "Person_Email", referencedColumnName = "Email", nullable = false)}
)
public Collection<Person> getPeopleAddressed(){
return this.peopleAdd;
}
public void setPeopleAddressed(Collection<Person> people){
this.peopleAdd = people;
}
}
public class AddressId implements Serializable
{
private String address;
private int number;
public AddressId(){}
public AddressId(String address, int number) {
super();
this.address = address;
this.number = number;
}
...
}
#Entity
#Table(name = "Person", schema = "YouDroop", uniqueConstraints =
{ #UniqueConstraint(columnNames = "NickName"),
#UniqueConstraint(columnNames = "Password") })
public class Person implements Serializable
{
...
private Collection<Address> addresses = new HashSet<Address>();
...
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "peopleAdd")
public Collection<Address> getPersonAddresses(){
return this.addresses;
}
public void setPersonAddresses(Collection<Address> addresses){
this.addresses = addresses;
}
}
Since you placed you #ManyToMany annotation on your getter method (or property) and not on the field. The mappedBy attribute should reference the property instead and not the field.
#ManyToMany
public Collection<Person> getPeopleAddressed() {
...
}
So your mappedBy attribute should have been
#ManyToMany(mappedBy="peopleAddressed")
public Collection<Address> getPersonAddresses() {
...
}
I have two classes as below
#Entity
#Table(name = "Employee", schema = "...", catalog = "...")
public class EmployeeEntity implements Serializable, UserDetails {
#Id()
#Column(name = "EmployeeID", nullable = false, insertable = true, updatable = true, length = 20)
#Basic
#Column(name = "UserName", nullable = true, insertable = true, updatable = true, length = 20)
private String username;
#OneToMany
#JoinColumn(name="UserName")
private Set<EmployeesGroupsEntity> employeeGroups;
//Getter and setters
}
and
#Entity
#Table(name = "EmployeesGroups", schema = "...", catalog = "...")
public class EmployeesGroupsEntity implements Serializable {
#Id
#Column(name = "UserName", nullable = false, insertable = true, updatable = true, length = 20)
private String username;
#Basic
#Column(name = "Group", nullable = false, insertable = true, updatable = true, length = 255)
private String groups;
}
Now, to access the objects, I have the spring data rest repositories as below
#RepositoryRestResource(collectionResourceRel = "Employee", path = "Employee")
public interface IEmployeeRepository extends PagingAndSortingRepository<EmployeeEntity, String> {
EmployeeEntity getByUsername(String userName);
EmployeeEntity getByEmailAddress(String emailAddress);
}
and
#RepositoryRestResource(collectionResourceRel = "EmployeesGroups", path = "EmployeesGroups")
public interface IEmployeesGroupsRepository extends PagingAndSortingRepository<EmployeesGroupsEntity,String> {
}
with the above setup, I tried to access the URL
http://localhost:8080/Employee/12345
and I successfully got the result as below
{
"employeeId" : "12345",
"username" : "firstx",
"_links" : {
"self" : {
"href" : "http://localhost:8080/Employee/12345"
},
"employeeGroups" : {
"href" : "http://localhost:8080/Employee/12345/employeeGroups"
}
}
}
As a next step, when I access the URL
http://localhost:8080/Employee/12345/employeeGroups
i get the output as
{ }
Subsequently, I also tried with the header "text/uri-list". When i do this I get a response code of 204.
Please help me in resolving the issue.
Thanks
After giving up.. Found the answer after stumbling upon another question.
I just had to annotate the relationship with RestResource(exported=true)
#Entity
#Table(name = "Employee", schema = "...", catalog = "...")
public class EmployeeEntity implements Serializable, UserDetails {
#Id()
#Column(name = "EmployeeID", nullable = false, insertable = true, updatable = true, length = 20)
#Basic
#Column(name = "UserName", nullable = true, insertable = true, updatable = true, length = 20)
private String username;
#OneToMany
#RestResource(exported = true)
#JoinColumn(name="UserName")
private Set<EmployeesGroupsEntity> employeeGroups;
//Getter and setters
}