Given entity Car with a collection of Wheels:
#var Collection<Wheel>
#ORM\ManyToMany(cascade={"all"}, orphanRemoval=true)
#ORM\JoinTable(
joinColumns={#ORM\JoinColumn(onDelete="CASCADE")},
inverseJoinColumns={#ORM\JoinColumn(unique=true, onDelete="CASCADE")}
)
There's a unique constraint preventing a Wheels being attached to two Cars, and cascade deletion and orphan removal is enabled (when Car gets deleted, its Wheels will also be deleted).
The Job is to transfer a Wheel from one Car to another.
Since the Wheel doesn't know of its relation to Car (there are reasons for it, the example is simplified), you cannot update a Wheel but instead have to update the two Cars.
First try:
Remove the wheel from the first Car
Attach it to the second Car
Update the first Car
Update the second Car
Third step deletes the Wheel. Bad.
Second try:
Remove the wheel from the first Car
Attach it to the second Car
Update the second Car
Update the first Car
Third step violates the unique constraint. Bad.
I can't think of a way to transfer the Wheel. Any help appreciated.
Related
I am working on a "Buy/Sell Item" functionality for an rpg game. If I am correct following actions need to happen in a single transaction
Get player based on playerID from "Players" table
Check if player has enough gold, if so create new item object
Write new item object to "Items" table, where owner is based on pllayerID
Update "Players" table row where owner is playerID, deduct gold based on item cost
If in above players gold changes while transaction is running or step 3 or 4 fail to execute simultaneously transaction should fail.
I've read the docs and can see that DynamoDB has TransactWriteItems and TransactGetItems which seem to be perfect for this, but are separate. Can I somehow use them in a single transaction?
Once you have your playerID, you should be able to merge step 4 into step 2 and then do steps 2-3 within one TransactWriteItems:
UPDATE the value of the gold conditionally - if enough gold is present, deduct the item cost immediately, else condition fails, and so does TransactWriteItems.
If you made it here, there was enough gold, and you can create and write the new object to the Items table.
Edit for explanation as to why this works:
TransactWriteItems groups the actions "Update gold" and "put item" as a single
all-or-nothing operation: either they both succeed or they both fail. And if another operation interferes, they also both fail (no race condition).
For example:
If there is not enough gold, the update fails, so the add item also fails.
If adding the item fails, the changes made to the gold will not be kept (the update will "fail")
If another operation is modifying the gold amount, both fail.
Essentially, it is impossible to either:
subtract the gold, but not add the item
add the item but not subtract the gold
Because they are both within the TransactWriteItems operation, either both happen, or neither does.
You can find an example in Java here. (For your use case, you can simply drop the customer validation and change "product status update" to "player gold update" and "add order" to "add item".)
For more details, see TransactWriteItems documentation here.
A totally neo4j noob is talking here,
I like to create a graph to store a set of users, a typical user is as follows:
CREATE
(node_1 {FullName:"Peter Parker",FirstName:"peter",FamilyName:"parker"}),
(node_2 {Address:"Newyork",CountryCode:"US"}),
(node_3 {Location:"Hidden"}),
(node_4 {phoneNumber:11111}),
(node_5 {InternetEmailAddress:"peter#peterland.com")
now the problem is,
Every time I execute this I add 5 more nodes.
I know I need to use a unique key, but all example I saw can use a unique key for a specific node. So how can I make sure a user doesn't get added if it already exists(I can use email address as unique key).
how do I update the nodes if some changes occur. for example, after a week I want to update the graph to contain the following instead of the previous one.(no duplicates)
CREATE(node_1 {FullName:"Peter Parker",FirstName:"peter",FamilyName:"parker"}),(node_2 {Address:"Newyork",CountryCode:"US"}),(node_3 {Location:"public"}),(node_4 {phoneNumber:11111}),(node_5 {InternetEmailAddress:"peter#peterland.com"),(node_6 {status:"Jailed"})
(NOTE the new update changed location to "public" and added a new node for peter
Seeing as you had a load of nodes anyway.
Some of the data you have modelled as Nodes are probably properties as the other answer suggests, some are possibly correctly modelled as Nodes and one could probably form the or a part of the relationship.
Location public/hidden can be modelled in one of three ways, as a property on the Person, as a property between the Person and the Location or as the relationship type. To understand that first you need to have a relationship.
Your address at the moment is another Node, I think this is correct, but possibly you would want two nodes, related something like this:
(s:State)-[:IN_COUNTRY]-(c:Country)
YMMV and clearly that a US centric model, but you can extend it easilly enough.
Now you could create Peter with a LIVES_IN relationship:
CREATE (p:Person{fullName:"Peter Parker"}), (s:State{name:"New York"}), (c:Country{code:"US"}),
(p)-[:LIVES_IN]->(s), (s)-[:IN_COUNTRY]->(c)
For speed you are better off modelling two relationships which could be LIVES_IN_PUBLIC and LIVES_IN_HIDDEN which means to perform that update that you want above then you have to delete the one and create the other. However, if speed is not of the essence, it is common also to use properties on the relationship.
CREATE (p:Person{fullName:"Peter Parker"}), (s:State{name:"New York"}), (c:Country{code:"US"}),
(p)-[:LIVES_IN{public:false}]->(s), (s)-[:IN_COUNTRY]->(c)
So your complete Q&A:
CREATE (p:Person {fullName:"Peter Parker",firstName:"peter",familyName:"parker", phoneNumber:1111, internetEmailAddress:"peter#peterland.com"}),
(s:State {name:"New York"}), (c:Country {code:"US"}),
(p)-[:LIVES_IN{public:false}]->(s), (s)-[:IN_COUNTRY]-(c)
MATCH (p:Person {internetEmailAddress:"peter#peterland.com"})-[li:LIVES_IN]->()
SET li.public = true, p.status = "jailed"
When adding other People you probably do not want to recreate States and Countries, rather you want to match them, and possibly Merge them, but we'll stick to Create.
MATCH (s:State{name:"New York"})
CREATE (p:Person{name:"John Smith", internetEmailAddress:"john#google.com"})-[:LIVES_IN{public:false}]->(s)
John Smith now implicitly lives in the US too as you can follow the relationship through the State Node.
Treatise complete.
I think you're modeling your data incorrectly here - you're setting up each property of the person as a separate node, which is not a good idea. You don't have any linkages between those nodes, so with this data pattern, later on you won't be able to tell what Peter Parker's address is. You're also not using node labels, which I think could really help here.
The quick question to your answer about updating nodes is that you have to MATCH them, then use SET to modify a property. So if you had a person, you might do this:
MATCH (p:Person { FullName: "Peter Parker" })
SET p.Address = "123 Fake Street"
RETURN p;
But notice I'm making assumptions about the way your data is structured. I'll take that same data you provided, this might be a better way of creating it:
CREATE (node_1:Person {FullName:"Peter Parker",
FirstName:"peter",
FamilyName:"parker",
Address:"Newyork",CountryCode:"US",
Location:"Hidden",
phoneNumber:11111,
InternetEmailAddress:"peter#peterland.com"});
The difference with this suggestion is that I'm putting all the properties into a single node (instead of one property per node) and I'm applying the Person label to the node.
If you structured the data like this, then the update query I provided would work. Structuring the data like you have it, it's not possible to update Peter Parker's address, because there's no relationship between your node_1 and node_2
Hi all,
I have 3 tables in an access 2010 database:
Crew: CrewID; Name; Adres;...
Voyage: VoyageId; Voyage name; Departure harbour; Arrival harbour
Crewlist: CrewlistId, VoaygeId, CrewId, Rank
The VoaygeId and CrewId from the Crewlist table are linked (relation) to the autonumber ID's from tables 2 and 1.
My first and main question is: Upon boarding everyone has to ‘sign in’ selecting the voyage and there name, and assign them a roll (of to be donde by the responsible officer). How can I make a form that lets the users browse through the voyagenames and crewnames in stead of the ID’s uses in the ‘mother’ table (table 3: Crewlist)
2nd question: how can I make sure that someone isn’t enrolled twice for the same voyage (adding same voyagenumber and same crewId number in crewlist). This would preferably be blocked upon trying to add the same person a second time on a voyage.
To prevent duplicates in Crewlist, add a unique index to the table on both CrewId and VoyageId
It would be a good idea to add relationships and enforce referential integrity
You are now in a position to use the wizards to create a form based on Voyage and a subform based on CrewList with a combobox based on Crew
There are a number of refinements you could add.
Make sure you do not use reserved words like Name and do not put spaces in field names. You will thank yourself later.
See also create form to add records in multiple tables
I am being asked to clean unused Customers in our AX database. The challenge is defining "unused" of course.
Is there any diagram anywhere documenting the table's relationship in Dynamics AX 2009 ?
For example, I see the table LedgerJournalTrans has the "AccountNum" field. I guess I could extrapolate that if a Customer has no associated records in LedgerJournalTrans, it is unused but I think it may be a bit more complicated than this.
Anything else I should watch for ?
Thanks!
I have had to do this before, and it really isn't terribly challenging, you just have to do your due diligence. I wouldn't feel as confident with ian_scho's method because it only checks two tables, but I'd say his method gets the 80%.
I would say your best method is to copy the class Classes\InventUnusedDimCleanUp and modify the simple functions in the \run method.
This is a base class that basically does the following, except I'm going to substitute InventDimId with AccountNum for solidarity:
Insert every customer account (AccountNum) into an empty check table as a starting reference
Traverse the Data Dictionary\Tables tree node over every table in the AOT
While traversing, determine if the table is a candidate table to compare against
If it is a candidate table, then traverse each field and determine if it's a candidate field by checking if it is an EDT of CustAccount or an EDT that extends it
If we determine it is a candidate field, then insert that into our container list of [TableId,FieldId]s
Next, loop through the container and for each tableId/fieldId, delete from our check table AccountNum's that DO exist in the candidate tables, so that we will be left with a check table of AccountNum's that were not found in any table
Lastly, a step you will probably do manually, but it will delete from CustTable the customers that are remaining in the check table, which have been deemed unused
This should accomplish your task, but doesn't take in account any external systems or customization you may have...but it gets the 95%.
Don't forget customer transactions - In one company or across all of them?
And in AX 2012 the financial dimension framework may reference the customer table itself.
CustTable custTable;
CustTrans custTrans;
//DefaultDimensionView defaultDimensionView; // **AX 2012**
;
//Customer transactions not found.
setPrefix("#SYS119665");
while select crossCompany AccountNum, Party from custTable
notExists join custTrans
where custTable.AccountNum == custTrans.AccountNum
{
info (strFmt("%1 - %2", custTable.AccountNum, custTable.name()));
//// Check financial dimension definition, 'Customer' **AX 2012**
//select firstonly defaultDimensionView
// where defaultDimensionView.DisplayValue == custTable.AccountNum
// && defaultDimensionView.Name == "Customer"; //"Client" in some countries? May depend upon AX installation.
//if (defaultDimensionView)
//{
// warning("Financial dimension value exists.");
//}
}
Personally I'd advise against deleting ANYTHING on these systems. Produce a report about what percentage of master data is being used, and if the data negatively impacts on usability...
Then see if your boss forgets about the request :)
(Also posted as http://drupal.org/node/596860)
I would like to create a view showing only those groups of which I am not already a member (or a pending member). However, the obvious way of doing this (take the og_my view and change the filter "Organic groups: Group member" to false) does not work.
The reason is that the SQL query essentially returns one row for every user in the group that matches your conditions. If you're searching for yourself (as in og_my), each group node will only show up once; if you're not searching for yourself, each group node shows up N times, where N is the number of other group members. Thus the groups of which I'm already a member continue to be displayed as long as there's at least one other member.
Does anyone have a way around this?
Thanks, Adrian
You may not be able to achieve this in Views directly as it does not support subqueries. My SQL came out like so:
SELECT node.nid AS nid, node.title AS node_title FROM node node LEFT JOIN og_uid og_uid ON node.nid = og_uid.nid WHERE (node.type IN ('campaign','setting','system')) AND node.nid NOT IN (select nid from og_uid where uid = 1);
It is said you can programmatically forward the results of such a query into the Views system for theming.
Maybe a special handling of the argument Organic Groups:Member of a Group, Exclude Argument option?
I also posted to d.o in hopes of pushing the issue conversation onward.
Wild. OG Views Extra was made available on d.o three days after your first revision of this question. I haven't used it, but looks just like it may do it.
So why install this module? If you need finer-grained control. The
available user options:
Not a Group Member
Group Member or Site Admin
Group Member Only