Project

General

Profile

Actions

Bug #4294

closed

Synthetic Primary Key Not Being Reported Correctly

Added by lm at over 9 years ago. Updated about 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Target version:
Start date:
07/07/2015
Due date:
% Done:

0%

Estimated time:
2:00 h

Description

When I make my dbo extend Wt::Dbo::Dbo and call Wt::Dbo::Dbo::id() on it, it returns an incorrect number. On the other hand, when I get the object from the database, Wt::Dbo::ptr::id() returns the correct value. I cooked up a minimum working example: http://sprunge.us/PRRI. My database looks like this: http://sprunge.us/Lead. I compile like this: http://sprunge.us/hjVh , and run like this: http://sprunge.us/VOaF. I'll attach these to this issue to make sure the code still exists in the future.

The output is like this:

getting meals...

begin transaction

select "id", "version", "name" from "meal"

meal

meal

commit transaction

meal first meal has id 22183448 and ptr_id = 1

meal second meal has id 2 and ptr_id = 2

The numbers don't seem to be reliable from Wt::Dbo::Dbo::id(), so it looks like an uninitialized value; If I add another meal or two, the values change randomly.

Wt::Dbo::Dbo::id() is supposed to return the id of the object according to the docs: http://www.webtoolkit.eu/wt/doc/reference/html/classWt_1_1Dbo_1_1Dbo.html#ae1f77ea4a99f84e0e7561001c5e6d1fb "Returns the database id of this object, or Wt::Dbo::dbo_traits::invalidId() if the object is associated with a session or not yet stored in the database." (note that the odd value I'm seeing I don't think is invalidId=--1).


Files

build output.txt (671 Bytes) build output.txt lm at, 07/07/2015 02:53 PM
database.txt (208 Bytes) database.txt lm at, 07/07/2015 02:53 PM
run.txt (467 Bytes) run.txt lm at, 07/07/2015 02:53 PM
source.txt (1.07 KB) source.txt lm at, 07/07/2015 02:53 PM
main.cpp (1.69 KB) main.cpp New and improved main.cpp lm at, 07/10/2015 07:32 PM
Actions #1

Updated by Koen Deforche over 9 years ago

  • Status changed from New to Feedback
  • Assignee set to Koen Deforche

Hey,

You're copying the 'meal' object by value. That's not something that's supported. Since I don't know how that should behave we'll probably make the Wt::Dbo<> copy constructor private.

Koen

Actions #2

Updated by lm at over 9 years ago

Oh, interesting. I haven't looked at the code, but would it be difficult to add copy and move constructors?

Actions #3

Updated by lm at over 9 years ago

I might as well ask about copy and move assignment operators, too :-) They should either be =delete or defined properly while we're at it.

Actions #4

Updated by Koen Deforche over 9 years ago

Hey,

What if you have two different C objects representing the same database object. How should that behave? Should a change in one be reflected in the other? In the database version? etc... The main assumption of an ORM is that an in-memory copy of a persisted object (e.g. which has a database counterpart) serves as a kind of 'cache'/'proxy' towards the database object. It's not clear how to extend this to multiple in-memory copies of the same object (within a single session).

Koen

Actions #5

Updated by lm at over 9 years ago

I can buy that, thanks. I deleted my object's copy ctor, and Wt::Dbo::Dbo's should probably =delete, too :-). While we're here, I guess we should make sure that move semantics work as they ought. I'll try to test that out soon, and report back.

Actions #6

Updated by lm at over 9 years ago

It looks like the hangman example does the same thing in Session.C:179 ? (It copies a Wt::Dbo::Dbo.)

Actions #7

Updated by lm at over 9 years ago

I did a bit of work on getting an object extending Wt::Dbo::Dbo out of a Wt::Dbo::ptr, and putting it into a vector. I'm uploading a new cpp;

In the business object, I have defined:

C::C()=default and C::C (C&&)=default; which leaves C::C (C const &) deleted (by omission; see rule of 3). Then, it's necessary to use .modify() to get a non-const ptr, and std::move() to make sure the copy constructor isn't invoked. It looks like there is no UB (uninitialized values uncovered).

Actions #8

Updated by Koen Deforche over 9 years ago

Hey,

Hangman seems indeed guilty of that and isn't setting the good example. I've instead decided to leave the copy constructor, but properly initialize the meta data, so that self() will return a null ptr in the copy.

Disabling the copy operation all together is a bit too restrictive for a generic base class.

Regards,

Koen

Actions #9

Updated by Koen Deforche over 9 years ago

  • Status changed from Feedback to Resolved
Actions #10

Updated by lm at over 9 years ago

I almost disagree with leaving the copy constructor but creating copies that don't act the same as the original. I agree that disabling copy might be heavy-handed, but I guess a note in the docs explaining the behaviour would perhaps be as good as we can expect. Thanks!

Actions #11

Updated by Koen Deforche about 9 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF