Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CreateBulk fails when entity has only ID field #3944

Open
2 tasks done
t-coron opened this issue Feb 11, 2024 · 1 comment · May be fixed by #3945
Open
2 tasks done

CreateBulk fails when entity has only ID field #3944

t-coron opened this issue Feb 11, 2024 · 1 comment · May be fixed by #3945

Comments

@t-coron
Copy link

t-coron commented Feb 11, 2024

Hi, thanks for an awesome library!

I want to create entities with M2M relationship by CreateBulk().

The problem is that CreateBulk() throws an error if entity has only ID field.
failed creating group: add m2m edge for table group_users: Error 1048 (23000): Column 'group_id' cannot be null

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

We cannot create M2M entities through CreateBulk if entity has only ID field.
(Or, is this the expected behavior?)

Expected Behavior 🤔

CreateBulk succeeds even if entity has only ID fied.

Steps to Reproduce 🕹

We first define two simple entities with M2M relationship like below.

// ent/schema/group.go
func (Group) Fields() []ent.Field {  // This has only ID field if name field is omitted
	return []ent.Field{field.String("name").Optional()}
}
func (Group) Edges() []ent.Edge {
	return []ent.Edge{
		edge.To("users", User.Type),
	}
}

// ent/schema/user.go
func (User) Fields() []ent.Field {
	return []ent.Field{field.String("name").Default("unknown")}
}
func (User) Edges() []ent.Edge {
	return []ent.Edge{
		edge.From("groups", Group.Type).
			Ref("users"),
	}
}

This is my create function with CreateBulk().

func Create(ctx context.Context, client *ent.Client) error {
	u, err := client.User.CreateBulk( // this is OK
			client.User.Create().SetName("user1"),
			client.User.Create().SetName("user2"),
			client.User.Create().SetName("user3"),
		).Save(ctx)
	if err != nil {
		return fmt.Errorf("failed creating user: %w", err)
	}
	log.Println("user was created: ", u)

	g, err := client.Group.CreateBulk( // name field is omitted
		client.Group.Create().AddUsers(u[0], u[2]),
		client.Group.Create().AddUsers(u[1]),
		client.Group.Create().AddUsers(u[1], u[0]),
	).Save(ctx) // We got an error here

	if err != nil {
		return fmt.Errorf("failed creating group: %w", err)
	}
	log.Println("group was created: ", g)
	return nil
}

Then, we got the following error.

driver.Exec: query=INSERT INTO `users` (`name`) VALUES (?), (?), (?) args=[user1 user2 user3]
user was created:  [User(id=1, name=user1) User(id=2, name=user2) User(id=3, name=user3)]
driver.Tx(3ab07907-718f-43b9-92ae-2585c8680838): started
Tx(3ab07907-718f-43b9-92ae-2585c8680838).Exec: query=INSERT INTO `groups` VALUES () args=[]
Tx(3ab07907-718f-43b9-92ae-2585c8680838).Exec: query=INSERT INTO `group_users` (`group_id`, `user_id`) VALUES (?, ?), (?, ?), (NULL, ?), (NULL, ?), (NULL, ?) ON DUPLICATE KEY UPDATE `group_id` = `group_users`.`group_id`, `user_id` = `group_users`.`user_id` args=[1 1 1 3 2 1 2]
Tx(3ab07907-718f-43b9-92ae-2585c8680838): rollbacked
failed creating group: add m2m edge for table group_users: Error 1048 (23000): Column 'group_id' cannot be null
exit status 1

It seems to me that ent generates the wrong query to insert group records.

query=INSERT INTO `groups` VALUES () args=[]

I think the expected query is this (because we want to insert 3 records). :

query=INSERT INTO `groups` VALUES (), (), () args=[] // for mysql
or
query=INSERT INTO `groups` (`id`) VALUES (NULL), (NULL), (NULL) args=[] // no dialect, maybe ?

The current workaround is to use three Create().Save(ctx) funcs instead of CreateBulk().

Your Environment 🌎

Tech Version
Go 1.21.2
Ent 0.13.0
Database MySQL
Driver https://github.com/go-sql-driver/mysql
@t-coron
Copy link
Author

t-coron commented Feb 12, 2024

This can be simply reproduced by:

// ent/schema/group.go
func (Group) Fields() []ent.Field { 
	return []ent.Field{field.String("name").Optional()}
}
func (Group) Edges() []ent.Edge {
	return []ent.Edge{}
}

and,

_, err := client.Group.
	CreateBulk(
		client.Group.Create(),
		client.Group.Create(),
		client.Group.Create(),
	).Save(ctx)
driver.Exec: query=INSERT INTO `groups` VALUES () args=[]

Sorry for my confusion.
It does not matter if the entity has M2M relationship or not.

@t-coron t-coron changed the title M2M CreateBulk fails when entity has only ID field CreateBulk fails when entity has only ID field Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant