Spring-Hibernate: How to submit a for when the object has one-to-many relations? - spring

I have a form changeed the properties of my object CUSTOMER. Each customer has related ORDERS. The ORDER's table has a column customer_id which is used for the mapping. All works so far, I can read customers without any problem.
When I now e.g. change the name of the CUSTOMER in the form (which does NOT show the orders), after saving the name is updated, but all relations in the ORDERS table are set to NULL (the customer_id for the items is set to NULL.
How can I keep the relationship working?
THX
UPDATE: Mapping Info
The Orders are mapped on the Customer side
#OneToMany
#JoinColumn(name = "customer_id")
#OrderBy("orderDate")
private Collection<Order> orders = new LinkedList<Order>();
UPDATE
Seems like adding a
#SessionAttributes("customer")
to my model, changing the method to
public String saveTrip(#ModelAttribute("customer") Customer customer, BindingResult result, SessionStatus status) {
if (!result.hasErrors()) {
this.tripManager.saveTrip(trip);
}
else {
logger.debug("Form data included errors, did not save data");
BindingUtils.logBindingErrors(result, logger);
}
status.setComplete();
return "redirect:/customers/";
}
Could solve the issu. But is this a good way of solving it???

One way would be not to submit the CUSTOMER Object from the form.
Instead submit the customer, submit only the customers ID and the new Name. In the controller you have to load the Customer by the submitted ID and then update the Name. And persist the Customer again.

HI,
Make cascade="none" attribute of many-to-one relationship from order side.
Thanks.

Related

How to retrieve an Entity Object just with #Id (Proxy object), check if it exists and assign it to a #ManyToOne association

I have an entity Product which have many fields and associations (around 60).
And a table ProductView which has a #ManyToOne(fetch = FetchType.LAZY) association with Product.
Is there a optimal way to retrieve Product object and assign it to ProductView ?
If its used JPA findById(productId) or JPQL/EntityManager selects-> It will retrieve all products fields and associations
Product product = productRepository.findById(productId);
ProductView productView = new ProductView(product);
save(productView);
If its used JPA getOne -> It solves the problem but the Proxy can throw error if Product does not exists. And this error can not be handled because it happens at runtime.
Product product = productRepository.getOne(productId);
ProductView productView = new ProductView(product);
save(productView);
If a DTO is used or Interface which refers to the same Product Table -> We will get just an object with Id field, but a lot more processes will need to be added (Which I am not familiar with)
Delete foreign keys from ProductView table (#ManyToOne -> #Column) and simple assign productIds. But in this way, there will be no logic connection between tables.
ProductView DB
How usually developers avoid this problem ?
I don't understand what the problem is. Just use getOne approach and at the end of your method, use flush which will throw the constraint violation exception that you can handle. This is the way to go.

belongsToMany with nullable foreign - Laravel 5.8

in my Laravel project i get this database structure:
Products
Id
Name
Orders
Id
Total
Order_Product
Product_id (nullable)
Order_Id
Details
In my Order model I make belongsToMany retaltionship with Product model:
public function products() {
return $this->belongsToMany(Product::class)->withPivot('Details');
}
The Problem is when I try to get the Order Products Collection
$order->products();
I don't get rows with nullable product_id, Any solution please ? Thank you.
Laravel support "Null Object Pattern" since version 5.5 which allows you to define a default model that will be returned if the given relationship is null.
Try using the following code:
public function products() {
return $this->belongsToMany(Product::class)->withDefault()->withPivot('Details');
}
Most likely, you don't get "nullable" products because you have a relation Order->Products. When you call $order->products(), eloquent tries to get all Product entities that are connected to your Order via product_id field. So, if field is empty, then you can't get Product because there is no connection.
One of the solutions is:
create another entity like OrderLine(Order_Product table); add methods like $orderLine->details() and relation to Product like $orderLine->product()
add relation to OrderLine inside Order - $order->line() or $order->info() etc. -> Order hasMany OrderLine
then use $order->line() to get an order's details and products (if exists)
p.s. I've compiled it in my head so it might need some code adjustments.
Good luck

Laravel relationship between two tables

I'd like your input on this.
I have a Customer_table with a field name. I have another table called Reservation_table with a Customer_name field.
How can I relate them in such a way that I'd see all the bookings by the specific customer?
In Reservation_table you should have a field(foreign key) userid in order ta have a user for each reservation.
You can using primary key - foreign key relationship to relate/join those two tables. Also, instead of having a 'Customer_name' field as your FK referring to 'name' field in 'Customer_table' table, it is better to have an id (unique) generated for each customer; This way you can have an efficient way of uniquely identifying and relating customer across tables; can save space on Database side as well. Hope this helps!
If you want to use eloquent you must first define a relationship.
One reservation belongs to a user. Here is how to define the relationships:
Inside the Reservation model:
public function user()
{
return $this->belongsTo('App/User'); //User model
}
To define the inverse you do the following:
Inside User model:
public function reservations()
{
return $this->hasMany('App/Reservation'); // Reservation Model
}
Now you can do the following in your controller:
$reservations = Auth::user()->reservations;
Now you have all reservations by the currently logged in user.
I am not sure if I got the question right so ask away.

Saving complex view model using Entity Framework 4.3

I have Customer, Order and OrderItem tables. OrderItem.OrderID points to Order.ID; and Order.CustomerID points to Customer.ID i.e. the common Customer -> Order -> OrderItem setup.
And I have a view model – Customer which contains Order objects and then OrderItem objects as well.
If the user creates a new Customer, new Order and new OrderItems on a view, which are then bound to the Customer view model object (containing all Customer, Order, OrderItem data); is there a way to save this Customer view model using EF?
My confusion comes from the fact that, since Customer, Order, OrderItem(s) are all new records; which means the Customer.ID (auto-incremented number) has not been generated yet (record not saved yet); so how does EF know what ID to use when saving Order.CustomerID?
Do I need to save Cusomer first, get the Customer.ID, then save Order, then get Order.ID and then save OrderItem(s)?
Thanks.
You just call this:
context.Customers.Add(customer);
context.SaveChanges();
and if everything is correctly configured in your mapping EF will understand relations and correctly save customer first, retrieve its Id and use it for saving related orders. It will handle order items in the same way.
As long as you establish the objects relationships before saving it should work
customer.Orders = new List<Orders>();
customer.Orders.Add(order);
order.OrderItems = new List<OrderItems>();
order.OrderItems.Add(orderItem);
context.Customer.Add(customer);
context.SaveChanges();

ASP.Net MVC View returned, but how can I show additional information?

I have a SQL database with has the following: Customer, Item, Clothing and Food.
Item holds a key to Clothing or Food.
Item also holds a key to Customer. Therefore a customer can have an item, which may be of food or clothing.
I am using ADO.Net Entity Framework and have this generated automatically.
I currently have the following set-up: A person may enter their ID on the webpage and this is sent via a form post where the controller picks it up and queries the database using LINQ to get the customer. The customer view (details) is then returned. I can now see all the customer details etc.
However, what I want is to be able to see the items the customer has, the different food items and clothing items, but I am unsure how to do this. I also want to be able to allow the user to edit one field of the clothes and food items tables. Any idea how I would implement this?
Here is an ActionResult in my CustomerController:
public ActionResult Details(int id)
{
var cust = (from c in dataModel.Customers
where (c.MembershipID == id)
select c).First();
return View(cust);
}
I can also write cust.Items which is the entity which I want to display in the view with the customer (their items). How would I display this in the view also?
Hopefully this makes it a little more clear on what I am trying to achieve and how.
Thanks.
Using Entity Framework, if you're tables are linked properly with the right foreign keys and all that then your Customer entity should have a property that is a collection of Items.
You could also create your own strongly typed ViewModel that has a field for Customer and implement your own properties for Clothing and Food and populate those with another query.
This question was asked last night but its similar. The guy in the question wanted information to populate a dropdown passed in. You want something similar, not for a dropdown, but to fill in textboxes to edit. How to properly populate drop downs from ViewData in controller on multiple views in ASP.NET MVC
To create a ViewModel start by creating a new class and name it CustomerAndItemsViewModel, for example.
public class CustomerAndItemsViewModel
{
public Customer Customer { get; set; }
public IQueryable<Items> Items { get; set; }
}
public ActionResult Details(int id)
{
var cust = (from c in dataModel.Customers
where (c.MembershipID == id)
select c).First();
var items = (from i in dataModel.Items
where (i.MembershipID == cust.MembershipID)
select i;
return View(new CustomerAndItemsViewModel { Customer = cust, Items = items });
}
And don't forget that you will no longer be passing a Customer to your view. So you need to change the line at the top to something like:
#model Your.Path.To.CustomerAndItemsViewModel
Typically, if you want to pass back information that is not contained in just one of your entities, you have to create a class that encompasses more than one object. So, if you want a page that displays your customer information, and all their items (which they can then edit), you would need to have a the controller action pass back a "CustomerAndItems" object (or something similarly named). This object would hold a reference to the Customer as well as a collection of their Items. (You build the CustomerAndItems object within your Action.)
Then, your view would be strongly typed to CustomerAndItems, and you can then display each piece of information as you normally would.

Resources