Zend Framework Doctrine insert one-to-many - zend-framework

Amongst order tables i have a Customers table and Addresses table. A customer can have many addresses so I have setup a one-to-many relationship in a yaml file. The thing is the id for the Customers table is auto generated so I would not know the Customers_id until after the insert however, the Customers_id is a foreign key in the Addresses table.
The information for both tables is captured on the same form although each set of data is in a subform. How do I get Doctrine to insert the data into the Customers table then fetch the Customers_id just entered and use it as the foreign key for the Addresses table.
Hope I have been able to get the essence of the question across.
BTW I am using Zend Framework and Doctrine 1.2.3

Once you do $customer->save(), you may use $customer->id (if "id" is the Customers_id column name of your customer table) to get the Customers_id to put in Addresses table.

Once you do $customer->save(); the following statement $customer->identifier(); should give you the id.

Assuming you are using Doctrine 1.x you could do the following:
$cusomer->Address[] = $address; // Assign multiple addresses in this manner
$customer->save();
This will first save the customer details to the db and then store the address data. Since doctrine understands the relationship between customer and address, the ORM will insert the customer id in the address table. Further this will be run within a transaction by Doctrine which ensures that if one of the operations fail the entire transaction will be rolled back.

Related

Can't add or edit records in form after updating relationship MS Access

Previously I had a Payment table's Form and a Current Tenant's Table's form. The Payment table was related with the Current Tenant's email address.
Later I realized the Payment table needed to include details of old tenants. So i created an append query to create a table containing details of all the tenants. And I changed the relationship so that the payment table is related to the email address from all tenant's table. Now using the Form, if i try to add a record using the form, it shows "You can't go to the specified record" and if i try to edit the records, it displays "The record set is not updateable". But i can add and edit record using the table. This problem only exists when i try to include the "Name of Tenant", "Tenant's Contact Information" or any other field from the "All Tenant's Table" in the form. How can i fix this?
Note: The email address in All tenant's contains duplicate records due to different Check out and Check in date. Except those, all other records are same.
When you join multiple tables in Access in order to allow updates across both tables, you need to join using a Primary Key.
Here is a great reference on the subject of Primary Keys.
Be sure that your "Current Tenants" table uses email address as a primary key, and then join it to the "Payment Table". The Payment table should also have a primary key (likely an 'auto number' field).
Ok, i found a way to solve the problem... I edited the relationship so that the All tenant's table is joined with Current tenant's table by Type 3 relationship. And Then joined the All tenant's table with the Payment table... It then solved the problem...

JPA fetching too many entries

I have a Customer Entity with a OneToMany relationship to an Invoice Entity.
In plain old sql i can do "select customer_name,customer_age,[some other fields] from customer, invoice where ... [put some filtering here]", which gets me exactly one record with the fields i need.
In JPA i use "select c from Customer c join c.invoiceCollection where ... [same filtering as above]"
This works, but i get the Customer entity with all its associated invoices.
This is nonsense, because i pull a huge amount of (invoices) data from the database, which i do not need. I need only my customer data with exactly one invoice, as specified in the where clause.
To make things worse, i have to loop over the Customer.invoiceCollection in order to find the one specific invoice needed. This costs me even more time plus it exposes my "where" clause to the middle-tier.
Question: is there a JPA select syntax which fetches exactly one record from a one-to-many relationship, as defined in the where clause?
Things tried so far:
a) lazy loading. This does not work, throws an exception whenever i try to access Customer.invoiceCollection.
Even if it worked, i'd get a Collection with some 1000 entries, which i do not need.
b) changed my jpa statement to "select c,i from Customer c join c.invoiceCollection i where ...". This returns me an array of objects, which i have to manually map to a Customer / Invoice entity.
It works, but it makes the ORM philosophy obsolete. If i perform all the mapping from relational database records/fields to java objects manually in my code, why do i need JPA?
This is one of the most infuriating things about JPA. For example, you NEED the OneToMany side if you want Customer to cascade delete Invoices. In most cases you'd like to tell Invoices to delete itself when a Customer is deleted so that Customer does not necessarily need to know about Invoice.
My suggestion for you is that you keep the OneToMany there but get the Lazy Loading working. In your code, do not access "Customer#getInvoices" directly (unless you really need all of them).
This will allow you to do queries on customers that join to invoices without loading them.
I'm guess the exception you are getting just has to do with transaction boundaries which can be easily fixed.
For a lot of these relationships I often add the OneToMany as a private instance variable but I don't create the #getter method. That way I can use it in queries, setup cascade delete, etc. but I don't provide a way to accidentally load thousands of invoices from a customer.
Oh, and for those queries where you need exactly one invoice with its associated customer you should just do the JPA query on the Invoice and then call #getCustomer on that invoice object. That will be eagerly fetched for you.
If you need exactly one invoice with the related customer, why don't you create a query simply based on Invoice?
select i from Invoice i where [same filtering..]
You should not use one-to-many relationship in this case.
One-to-many relationships are suitable for situations when objects at "many" side are logical parts of object at "one" side (e.g. relationship from Invoice to InvoiceLine).
In you case you need a unidirectional many-to-one relationship from Invoice to Customer, so that you can query it as follows:
select i from Invoice i where ...
Then you can use customer field of Invoice to access Customer or filter by its properties.

How can I replicate core data model using a traditional relational database?

I have my app using core data with the data model below. However, I'm switching to a standard database with columns and rows. Can anyone help me with setting up this new database schema?
First of all you need to create tables for each of the Entities and their attributes (note I added "id" to each of the tables for relationships):
Routine (name, timestamp, id)
Exercise - this looks like a duplicate to me, so leaving one only here (muscleGroup, musclePicture, name, timeStamp, id)
Session (timeStamp, id)
Set (reps, timeStamp, unit, weight, id)
Now that you have tables that describe each of the entities, you need to create tables that will describe the relationships between these entities - as before table names are in capitals and their fields are in parenthesis:
RoutineExercises (routine_id, exercise_id)
SessionExercises (session_id, exercise_id)
ExerciseSets (exercise_id, set_id)
That's it! Now if you need to add an exercise to a routine, you simply:
Add an entry into Exercise table
Establish the relationship by adding a tuple into RoutineExercises table where routine_id is your routine ID and exercise_id is the ID of the newly created entry in the Exercise table
This will hold true for all the rest of the relationships.
NOTE: Your core data model has one-to-many and many-to-many relationships. If you want to specifically enforce that a relationship is one-to-many (e.g. Exercise can only have 1 routine), then you will need to make "exercise_id" as the index for the RoutineExercises table. If you want a many-to-many relationships to be allowed (i.e. each exercise is allowed to have multiple routines), then set the tuple of (routine_id, exercise_id) as the index.

Many to many relationship with ADO.NET Entity Data Model

I've created many-to-many relationship with ADO.NET with extra order fields in the middle table.
So I have...
Customers
-customer_id
-customer_name
Orders
-order_id
Customers_to_Orders
-customer_id
-order_id
-seq
And now I don't really know how to add new orders to customers with specyfing order, any suggestions?
Create the order first.
Get the ID back for the order.
Then, create the link from the customer to the order.
you add the order to orders table first, and then add it to customer_to_orders preferably in one transaction.
if you're worried about the seq - it can be either identity or you can calculate "next seq" by querying customers_to_orders before adding new data.

Adding a property to an Entity Framework Entity from another table

I'm just starting out with the Entity Framework and ADO.NET Data Services and I've run into an issue that I can't seem to figure out. I have two tables, one that has user information and the other that has a created by field. Within the database, there isn't a foreign key between these tables. The user table contains an arbitrary Id, a username, and a display name. The created by field contains the user's username. In my entity I would like to have the user's display name since this is what I need to display and expose over the ADO.NET Data Service? I'm aware that I could restructure the database, but I was hoping that I could do the join using the username as I would in a SQL statement.
Thanks in advance,
-Damien
You can make a view using a join of both tables, and then use this object to display the user's name.
There's some info on mapping custom queries here.