Deleting and updating Many-to-Many Relationships using OpenJPA - jpa-2.0

I have a couple of entities that will be deleted. Those entities will have a couple Many-To-Many links. When updating a many-to-many link I am thinking I will just delete the original links in the joining table for that entity and just replace the link with a new link. But I am really confused on how that would work. How do you update a many-to-many relationship? Same thing goes for delete. If you have cascade for deletes set, then you would essentially delete that entity and the entities (collection, multiple entities I believe) that are linked to it. How would that work?
#Entity
#Table(name="QUICK_LAUNCH")
public class QuickLaunch implements Serializable {
...
#ManyToMany(fetch=FetchType.EAGER)
#JoinTable(name="QUICK_LAUNCH_PROVIDER",
joinColumns=#JoinColumn(name="QUICK_LAUNCH_ID"),
inverseJoinColumns=#JoinColumn(name="RESOURCE_ID"))
private List<Provider> providerList;
}
The thinking was that I would delete any links to a provider and just add new links. I could do that programatically, just delete links in the linking table, but I feel as though that should be handled by the ORM (is that an unreasonable feeling?).
Does anybody have any general words of wisdom for Deleteing Many-To-Many relationships,
Maybe I could just delete and update relationships using the actual entities...
Like say I have a quickLaunch with a list of providers... I set that list of providers to null (effectively removing that list of providers from that entity I would hope) I would then set that list of providers to a new list of providers... I of course would have to set up that list programatically. Does that sounds feasable or just freaking stupid?

That's the way to do:
removing a provider from the list will remove the association between the QuickLaunch and the provider (and thus delete the corresponding row from the join table);
adding a provider to the list will create the association between the QuickLaunch and the provider (and thus insert a row in the join table).

Related

Use DynamoDBVersionAttribute when creating a new DynamoDB Table in Java

I'm trying to add a DynamoDBVersionAttribute to incorporate optimistic locking when accessing/updating items in a DynamoDB table. However, I'm unable to figure out how exactly to add the version attribute.
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html seems to state that using it as an annotation in the class that creates the table is the way to go. However, our codebase is creating new tables in a format similar to this:
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);
List<AttributeDefinition> attributeDefinitions= new
ArrayList<AttributeDefinition>();
attributeDefinitions.add(new
AttributeDefinition().withAttributeName("Id").withAttributeType("N"));
List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>();
keySchema.add(new
KeySchemaElement().withAttributeName("Id").withKeyType(KeyType.HASH));
CreateTableRequest request = new CreateTableRequest()
.withTableName(tableName)
.withKeySchema(keySchema)
.withAttributeDefinitions(attributeDefinitions)
.withProvisionedThroughput(new ProvisionedThroughput()
.withReadCapacityUnits(5L)
.withWriteCapacityUnits(6L));
Table table = dynamoDB.createTable(request);
I'm not able to find out how to add the VersionAttribute through the Java code as described above. It's not an attribute definitions so unsure where it goes. Any guidance as to where I can add this VersionAttribute in the CreateTable request?
As far as I'm aware, the #DynamoDBVersionAttribute annotation for optimistic locking is only available for tables modeled specifically for DynamoDBMapper queries. Using DynamoDBMapper is not a terrible approach, since it effectively creates an ORM for CRUD operations on DynamoDB items.
But if your existing codebase can't make use of it, your next best bet is probably to use conditional writes to increment a version number if it's equal to what you expect it to be (i.e. roll your own optimistic locking). Unfortunately, you would need to include the increment / condition to every write you want to be optimistically locked.
Your code just creates a table, but then in order to use DynamoDBMapper to access that table, you need to create a class that represents it. For example if your table is called Users, you should create a class called Users, and use annotations to link it to the table.
You can keep your table creation code, but you need to create the DynamoDBMapper class. You can then do all of your loading, saving and querying using the DynamoDBMapper class.
When you have created the class, just give it a field called version and put the annotation on it, DynamoDBMapper will take care of the rest.

Ordered ManyToMany relation in Django with custom Field

In Django, I would like to have an ordered many-to-many-relation. Assume I have, say, the models OrderedList and Item, and I want to be able to insert Item()s into an OrderedList() at a specific index, I want to be able to retrieve the Item()s of an OrderedList() in their order and also to change the order of Item()s on an OrderedList
I already found Define an order for ManyToManyField with django and https://github.com/gregmuellegger/django-sortedm2m
Both the github repo and the accepted answer in the SO question are working with the same architecture: They create an additional integer field, say order_index, on the junction ("Through") table which represents the position of the Item() on the OrderedList().
Honestly, I do not like that too much. If I see this correctly, having the order stored on the junction table can create inefficiency when I want to reorder Item()s: Imagine, I want to change the position of an Item() on an OrderedList() which has n Item()s. This means O(n) database updates to reorganize the order indices.
I would like to avoid this. I think of an architecture where I have an ordinary many-to-many-relation and one additional column on the OrderedList table which holds a list of Item ids, say items_order. In this architecture, I need one database update and one list operation on items_order - which should be way faster, I guess.
I believe the best way for this is to create a custom model Field. The docs state how to create a custom model Field (https://docs.djangoproject.com/en/2.1/howto/custom-model-fields/) and I can create my items_order field like this. But I did not find how to make a custom Field which, besides creating the order_list, also creates the junction table and takes care of updating the items_order whenever a new related Item() is added or removed from the relation. I think, I should subclass the ManyToMany Field (https://docs.djangoproject.com/en/2.1/_modules/django/db/models/fields/related/#ManyToManyField). But I don't know how to do this, so could you give me some guidance here?

Basic List on Entity Form

In Dynamics CRM online, I can add a list of entities to another entity, for example a list of products to an opportunity.
Is there any way I can have a list that is not picked from pre-populated items, e.g. just a simple list of {number, date, text} that you type in each time you want to add to the list, not picking items from a pre-defined list.
I am just using the web interface to customise at the moment, but I am open to any suggestions.
EDIT:
So far i have;
Created two entities, proposal and proposal version
Added a 1:N relationship between proposal and proposal version
Added a sub-grid to the proposal form, tried to make it editable but it refuses to work
This lets me add new rows by opening up the proposal version form and adding a new one or picking from already created ones for other proposals but that is rather clunky for a simple list.
I don't want it to offer to search for previous entries, just let me add to the list by typing stuff in, surely this should be fairly simple?
If you want a pre-defined list of items that are simple (number, date, text..) then you can create an option set field in CRM. These lists are fixed and can only be extended by customising the system. An example option set field might be Organisation Type:
Prospect
Site
Head Office
...
If you want a pre-defined list that can be extended, you need to create a new entity. Following from the previous example, you would create a custom entity called Organisation Type and then create a record for each type you wanted, populating only the name field with the type: Prospect, Site etc.
Then you would add a lookup field pointing to the Organisation Type entity on any other entity that used the field, such as Organisation (Account).
You see how the custom entity still appears as simple data because you're only populating the name field, which can be text, a number etc. You can also apply security roles to this entity, limiting which users can create and delete options from your list.
Edit: to only allow the creation of new records in a subgrid, make sure the lookup attribute to the parent entity on the child entity is business required.

Forms - Managing OneToMany collection elements

Let's imagine these 2 entities:
ShoppingCart
creationDate
Item
name
shoppingCart # ManyToOne
I'm managing a ShoppingCart in a form with a CollectionType of Items
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
$builder
// ...
->add('items', CollectionType::class, array(
'entry_type' => ItemFormType::class,
// ...
}
I'd like my users to be able to add/remove items, which seems to me like a quite common need.
If I understand well, here is what I have to do:
Define the reverse OneToMany side of the ShoppingCart relation to Item
Make sure this relation have the cascade={"persist"} and orphanRemoval=true options
Initialize this items Collection into the constructor
Set the allow_add and allow_delete form option to true
Set the by_reference form option to false
Make sure andItem() & removeItem() functions are implemented into ShoppingCart
Set/unset the owning side relation to the ShoppingCart in addition to add/remove the Item from the ShoppingCart items collection
Keep the collection indexes within javascript so Doctrine can keep track of references
Am I forgetting something ?
I find it a big pain in the arse for me compared to the need and to other frameworks/ORMs
Is there a way to do it simpler ?
As I understand, your question is "why is it so complicated", isn't it?
Well, it's not. You've listed things multiple layers in your project. To exaggerate the point a little bit - why didn't you wrote that in order to create this form you need to install Symfony or even turn on your computer. ;-)
Anyway, most of these things are not required, others should be done before anyway.
Let's start with your OneToMany relation (Doctrine level).
ShoppingCart is your aggregate root (DDD term, but it doesn't matter if you follow DDD idea), which means you probably will do most of work on this object which will handle Items inside. If so, then you should have done inversed side of the relation, which covers these points (I think you went into details so much to make your list longer ;-), they all should be in one list item), but it takes a minute to do this stuff:
Define the reverse OneToMany side of the ShoppingCart relation to Item
Make sure this relation have the cascade={"persist"} and orphanRemoval=true options
Initialize this items Collection into the constructor
Make sure andItem() & removeItem() functions are implemented into ShoppingCart
Set/unset the owning side relation to the ShoppingCart in addition to add/remove the Item from the ShoppingCart items collection
This has nothing to do with forms. It's about how you want your entities to work with Doctrine.
Following two are not required:
Set the allow_add and allow_delete form option to true
Set the by_reference form option to false
They are about enabling/disabling features. You want them, so you need to use them. That's obvious and still not so much to do.
Last one:
Keep the collection indexes within javascript so Doctrine can keep track of references
This is the one that I actually don't understand. But what you need (in your case, because you're using allow_add/delete feature), is to provide JavaScript code that will create HTML for new row or delete existing one. But that's also just about copying prototype code. Also there are ready examples in Symfony's doc.
Let me answer myself in a simpler manner:
No I am not forgetting anything
No we can't do simpler
Some reasons are explained in #dragoste answer

Subsonic 3 and table relationships

I have something like this:
Order order = new Order();
Item item = new Item();
order.Items.Add(item);
order.Save();
How can I do this with Subsonic? The method that refere to a related table is IQueryable.
You have three options:
Set the foreign key in Item to the id of your Order object and save both.
Create a partial class which has a method "AddItem", encapsulating this functionality
Modify the T4 templates to allow you to do this automatically; unfortunately this feature doesn't come out of the box yet.
The advantage with Subsonic is that it is flexible, however you occasionally have to fill some of the gaps yourself.
If you are programming something like a shopping cart you can abstract that out into it's own class that can handle marrying the objects together. I personally think it works better than modify the generated objects.