#OneToOne is being ManyToOne
165 messages · Page 1 of 1 (latest)
im editing i sent this by accident ill edit to show the full case
here you go this is like the most relevant parts what do you think the issue may be?
There's no foreign key in your many table
One driver can have many vehicles
i dont want it to be many to many.... there is another entity down the road that will need a one to one too i need to have it as one to one as one student can use only one vehicle the "orginisation" is interested to track every student mode of transportation i have attached how i want it to look like
please note that one member use one vehicle and one driver use one vehicle
You'll need a composite primary key with driverid and memberid in the vehicle table
Otherwise it'll be one to many
but if i do it that way wont the member no longer receive the vehicle ID? like a member use a vehicle so wont it be more logical to have the vehicle registration in the member part?
You could make driverid and memberid a foreign key and driverid as the primary
check your Vehicle entity. If you want a one to one relationship with Driver, you gotta change the decorator to @OneToOne(() => Driver) and don’t forget @JoinColumn() that's what tells TypeORM which side owns the relationship. Otherwise, it defaults to many-to-one behavior.
well thats what i have done in the vehicle
@PrimaryColumn()
vehicleRegNum: number;
@OneToOne(() => Driver)
@JoinColumn()
vehicleDriverID: Driver;
// In Vehicle entity
@OneToOne(() => Driver, (driver) => driver.vehicle)
@JoinColumn()
vehicleDriverID: Driver;
// In Driver entity
@OneToOne(() => Vehicle, (vehicle) => vehicle.vehicleDriverID)
vehicle: Vehicle;
what i sent is the vehicle entity
isnt that a double relation?
like isnt that bi-directional relation? all i need is a uni-direction relation
can u pass the entire vehicle entity pls
sure
like the code
import {Column, Entity, JoinColumn, OneToOne, PrimaryColumn} from "typeorm";
import {Driver} from "../driver/driver.entity";
@Entity()
export class Vehicle {
@PrimaryColumn()
vehicleRegNum: number;
@OneToOne(() => Driver)
@JoinColumn()
vehicleDriverID: Driver;
@Column()
vehicleBrand: string;
@Column()
vehicleModel: string;
@Column()
vehicleType: number;
@Column()
vehicleCapacity: number;
}
entire vehicle entity class
create vehicle dto
import {Driver} from "../../driver/driver.entity";
export class createVehicleDTO {
vehicleRegNum: number;
vehicleDriverID: Driver;
vehicleBrand: string;
vehicleModel: string;
vehicleType: number;
vehicleCapacity: number;
}
and vehicle service
import {updateVehicleDTO} from "./dto/update-vehicle.dto"
import {Vehicle} from "./vehicle.entity";
import {Driver} from "../driver/driver.entity"
import {driverService} from "../driver/driver.service"
@Injectable()
export class vehicleService {
constructor(
@InjectRepository(Vehicle)
private readonly vehicleRepository: Repository<Vehicle>,
private readonly driverService: driverService
) {
}
@InjectRepository(Driver)
createVehicle(createVehicleDTO: createVehicleDTO): Promise<Vehicle> {
const vehicle = new Vehicle();
vehicle.vehicleRegNum = createVehicleDTO.vehicleRegNum;
vehicle.vehicleBrand = createVehicleDTO.vehicleBrand;
vehicle.vehicleModel = createVehicleDTO.vehicleModel;
vehicle.vehicleType = createVehicleDTO.vehicleType;
vehicle.vehicleCapacity = createVehicleDTO.vehicleCapacity;
vehicle.vehicleDriverID = createVehicleDTO.vehicleDriverID;
return this.vehicleRepository.save(vehicle);
}
//rest of the services
}
try this
?
@Column({ unique: true })
isnt @PrimaryColumn() enough?
man just try it
where i put it
in the vehicle entity above the driver field
@Entity()
export class Vehicle {
@PrimaryColumn()
vehicleRegNum: number;
@OneToOne(() => Driver)
@JoinColumn()
@Column({ unique: true }) // Ensure that each driver can only be linked to one vehicle
vehicleDriverID: Driver;
@Column()
vehicleBrand: string;
@Column()
vehicleModel: string;
@Column()
vehicleType: number;
@Column()
vehicleCapacity: number;
}
okay nvm then i'm sorry
"DataTypeNotSupportedError: Data type "Driver" in "Vehicle.vehicleDriverID" is not supported by "mysql" database."
okay so in the dto instead of passing the whole driver object
why not pass the driver id
how id do it
use driverservice to dind the approriate id?
`// In vehicle.entity.ts
import {Column, Entity, JoinColumn, OneToOne, PrimaryColumn} from "typeorm";
import {Driver} from "../driver/driver.entity";
@Entity()
export class Vehicle {
@PrimaryColumn()
vehicleRegNum: number;
// Change property name to better reflect what it is
@OneToOne(() => Driver, (driver) => driver.vehicle, { nullable: true })
@JoinColumn()
driver: Driver;
@Column()
vehicleBrand: string;
@Column()
vehicleModel: string;
@Column()
vehicleType: number;
@Column()
vehicleCapacity: number;
}`
export class createVehicleDTO { vehicleRegNum: number; driverId: number; // Change to just store the ID vehicleBrand: string; vehicleModel: string; vehicleType: number; vehicleCapacity: number; }
this is the entity and dto
then u update the service
`@Injectable()
export class vehicleService {
constructor(
@InjectRepository(Vehicle)
private readonly vehicleRepository: Repository<Vehicle>,
@InjectRepository(Driver) // Fix placement
private readonly driverRepository: Repository<Driver>,
private readonly driverService: driverService
) {}
async createVehicle(createVehicleDTO: createVehicleDTO): Promise<Vehicle> {
const vehicle = new Vehicle();
vehicle.vehicleRegNum = createVehicleDTO.vehicleRegNum;
vehicle.vehicleBrand = createVehicleDTO.vehicleBrand;
vehicle.vehicleModel = createVehicleDTO.vehicleModel;
vehicle.vehicleType = createVehicleDTO.vehicleType;
vehicle.vehicleCapacity = createVehicleDTO.vehicleCapacity;
// Find the driver by ID instead of directly assigning
if (createVehicleDTO.driverId) {
const driver = await this.driverRepository.findOne(createVehicleDTO.driverId);
vehicle.driver = driver;
}
return this.vehicleRepository.save(vehicle);
}
// Rest of the services
}`
hold up
@OneToOne(() => Driver, (driver) => driver.vehicle, { nullable: true })
@JoinColumn()
driver: Driver;
you are still doing it of type Driver here
why is this answer so counter intuitive i have to find the id to make the relation isnt there an easier approach to do it?
yes but you take the driver id from dto and u get the whole driver object in the service and u assign it to the class entity
it's better send simple data in the dto's and get your service to do the hard work
why in many to one it is not required to fetch the id?
that's a great question , i honestly don't know i just find it best practice to send simple data in dto rather than objects , it even make the frontend easier
i never coded with next js before , i only use java for backend and no sql database
it removes the relationships headache
i am not using next js and i cant control the framework it is predetermined by the instructor
this is why i dropped out of college
mfs want me to code in C
Have you made sure both the Vehicle and Driver entities have @OneToOne relationships to each other, and that the Driver entity doesn't have any @OneToMany or @ManyToMany relationships?
how would i do the one to one in the vehicle?
i dont want any foreign keys to driver entity*
i just need it to be like this
driver without any foreign keys
the foreign key of the driver in the vehicle
and there is no many to many no
Ohh
in that case, to get that strict one-to-one thing working without foreign keys messing up your Driver setup, you'll want the Vehicle to "own" the relationship by holding the foreign key to the Driver. Think of it as the Vehicle knowing who's driving it, and similarly, have the Member entity "own" a relationship with a Vehicle in a similar way.
yeah im desperate please tell me you lknow the solution
🙏 I just woke up too haha, Let's see if im rusty or not
im sorry but it really broke me down
if you need to take your time it is okay
want me to paste the entities, dtos and create service?
(although i already did but eh why not paste it again)
Sure
so driver.entity.ts
import {Column, Entity, PrimaryColumn} from "typeorm";
@Entity()
export class Driver {
@PrimaryColumn()
driverID: number;
@Column()
driverName: string;
@Column()
driverNumber: number;
@Column()
driverRegion: string;
}
create-driver.dto.ts
export class createDriverDTO {
driverID: number;
driverName: string;
driverNumber: number;
driverRegion: string;
}
driver.service.ts
import {Repository} from "typeorm";
import {Injectable, NotFoundException} from "@nestjs/common";
import {InjectRepository} from "@nestjs/typeorm";
import {createDriverDTO} from "./dto/create-driver.dto";
import {Driver} from "./driver.entity";
import {updateDriverDTO} from "./dto/update-driver.dto";
@Injectable()
export class driverService {
constructor(
@InjectRepository(Driver)
private readonly driverRepository: Repository<Driver>,
) {
}
createDriver(createDriverDTO: createDriverDTO): Promise<Driver> {
const driver = new Driver();
driver.driverID = createDriverDTO.driverID;
driver.driverName = createDriverDTO.driverName;
driver.driverNumber = createDriverDTO.driverNumber;
driver.driverRegion = createDriverDTO.driverRegion;
return this.driverRepository.save(driver);
}
//rest of the servuces
}
thats for driver
now for the vehicle
vehicle.entity.ts
import {Column, Entity, JoinColumn, OneToOne, PrimaryColumn} from "typeorm";
import {Driver} from "../driver/driver.entity";
@Entity()
export class Vehicle {
@PrimaryColumn()
vehicleRegNum: number;
@OneToOne(() => Driver)
@JoinColumn()
vehicleDriverID: Driver;
@Column()
vehicleBrand: string;
@Column()
vehicleModel: string;
@Column()
vehicleType: number;
@Column()
vehicleCapacity: number;
}
is that all?
create-vehicle.dto.ts
import {Driver} from "typeorm";
export class createVehicleDTO {
vehicleRegNum: number;
vehicleDriverID: Driver;
vehicleBrand: string;
vehicleModel: string;
vehicleType: number;
vehicleCapacity: number;
}
i still have the driver service
idk i messed my files im trying to fix it
atleast how it was
Alright, update VehicleService to fetch the Driver entity by ID and assign it to vehicleDriverID before saving the Vehicle, this will ensure the one-to-one relationship is correctly linked.
is there no more intuitive way to do it than fetching it?
i already have that functionality
this is in vehicle service
async findVehDriverByDriverID(vehicleDriverID: number): Promise<Driver> {
return this.driverService.findByDriverID(vehicleDriverID);
}
Well....
just tell me no if there isnt
Yeah, you could instead of fetching the Driver entity, you could perhaps directly assign the driverID to a vehicleDriverID column in the Vehicle entity and establish the relationship through that; that way, TypeORM handles the linking under the hood.
thats more intuitive and less intensive
i mean look at my DB
so how i should proceed from here
- Modify
Vehicleentity: Remove the direct relationship/foreign key to theDriverentity. - Instead, add
driverDriverId(matching yourDriver'sdriverId) to the vehicle entity. - TypeORM: Define a relation in
VehicleusingdriverDriverIdto connect to yourDriverentity.
just one thing i fixed the create vehicle and service i had some bad modifications
create vehicle
import {Driver} from "../../driver/driver.entity";
export class createVehicleDTO {
vehicleRegNum: number;
vehicleDriverID: Driver;
vehicleBrand: string;
vehicleModel: string;
vehicleType: number;
vehicleCapacity: number;
}
and vehicle service
@InjectRepository(Driver)
createVehicle(createVehicleDTO: createVehicleDTO): Promise<Vehicle> {
const vehicle = new Vehicle();
vehicle.vehicleRegNum = createVehicleDTO.vehicleRegNum;
vehicle.vehicleBrand = createVehicleDTO.vehicleBrand;
vehicle.vehicleModel = createVehicleDTO.vehicleModel;
vehicle.vehicleType = createVehicleDTO.vehicleType;
vehicle.vehicleCapacity = createVehicleDTO.vehicleCapacity;
vehicle.vehicleDriverID = createVehicleDTO.vehicleDriverID;
return this.vehicleRepository.save(vehicle);
}
driverDriverID as a number right?
Yep!
I see vehicleDriverID: Driver there in your DTO. Change that to vehicleDriverID: number (or whatever type Driver.driverId is). You want the ID, not the whole Driver object, in your DTO. Then in your service, it can stay the same vehicle.vehicleDriverID = createVehicleDTO.vehicleDriverID; since you are now passing just the driverID.
thats what i am doing now
so far what i done
replace vehicleDriverID: driver to VehicleDriveID: number in the dto and
@Column()
vehicleDriverID: number;
in entity
now how to proceed with the relation thats my main worry
Define the relationship in your Vehicle entity using decorators. Add @ManyToOne and @JoinColumn to link vehicleDriverID to the Driver entity. This tells TypeORM how they're related.
@ManyToOne? it is a one to one... thats why i have been breaking my head i want to make it a one to one but the typeorm is interpreting it as many to one
if it's one-to-one, use @OneToOne instead of @ManyToOne, and @JoinColumn. Make sure the Driver also has a @OneToOne and @JoinColumn pointing back to the Vehicle. Circular import energy if you do it wrong tho.
^
buddy i have been banging my head nonstop on the wall for 3 days
just to end up in the same place
a many to one when it should be 1 to 1
i still have to do the front end 🪦
Something like this?
// Vehicle entity
@ManyToOne(() => Driver, (driver) => driver.vehicles)
@JoinColumn({ name: 'driver_driverID' })
driver: Driver;
// Driver entity
@OneToMany(() => Vehicle, (vehicle) => vehicle.driver)
vehicles: Vehicle[];
Make sure the column names match your actual database columns (driver_driverID).
mopif... i need a one to one aka one driver has one vehicle
// Vehicle entity
@OneToOne(() => Driver, (driver) => driver.vehicle) // note the back reference
@JoinColumn({ name: 'driver_driverID' })
driver: Driver;
// Driver entity
@OneToOne(() => Vehicle, (vehicle) => vehicle.driver)
vehicle: Vehicle;```
one last question before i plop it in is this a uni-directional relation? meaning there will be only one side to it
Nah, that's bi-directional. Both Driver and Vehicle know about each other. Uni-directional means only one entity knows about the other, and you'd remove the vehicle property from the Driver entity and the back reference.
so when i do that will there be 1 relation or 2
bcs i want to avoid a situation like this
To avoid this, make sure you only define the @JoinColumn on one side of the relationship, and that the column name is correct. If you're going uni-directional, there will be one FK and that's it.
amazing thats whats needed let me test what we did
in vehicle entity
nvm i made it work
but it was along the line of what you did
// Bi-directional
class Driver {
vehicle: Vehicle; // <-- make sure this is there
}
// Uni-directional - access driver from vehicle
const theDriversVehicle = vehicle.driver;```
oh you fixed it already?
haha beat it to me :)))
yeah made sure to write this
@OneToOne(() => Vehicle, (vehicle) => vehicle.driver)
vehicle: Vehicle;
i forgot to import
ahhh yea
💀 okay i give up now-
Someone else pls help the dude, my heads hurting too 😭 ! we mut suffer together
im so cooked 🪦
I wish i would be more help but honstly this simple thing is just sooo confusing
yk whats funny? im not just resetting im deleting the database deleting the dist file and running again and then making a graph using mysql workbench
its not logical that a one to one should be this complex im reconsidering my life choices
just to confirm we are on the same page
in driver entity i added this
@OneToOne(() => Vehicle, (vehicle) => vehicle.driver)
vehicle: Vehicle;
after i imported vehicle
in vehicle entity
@Column()
vehicleDriverID: number;
@OneToOne(() => Driver, (driver) => driver.vehicle) // note the back reference
@JoinColumn({ name: 'vehicleDriverID' })
driver: Driver;
removed the join column mad it like this
and finaly in the create vehicle dto the vehicle drive is number like this vehicleDriverID: number;
In school, Groklearning I've achevied a high disinction in world for python immerdiate so like ts is def not my thing-
(85-99% High Distinction)
but it shouldnt be this tough i mean you know the coding logic im not so diffrent from you im wildly inferior coding wise
well not inferior but still FF SAKE
now what?
Can you share the entire database and all your code? You keep asking partial questions when you're trying to get help with the bigger picture
I sent all the relevant parts fpr vehicle and driver and i did sent the entire db
This is the full db
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Vehicle } from "../vehicle/vehicle.entity";
import { Member } from "../member/member.entity";
@Entity()
export class Driver {
@PrimaryGeneratedColumn()
driver_id: number;
@Column()
driver_name: string;
@Column()
driver_number: string;
@Column()
driver_region: string;
@OneToMany(() => Vehicle, vehicle => vehicle.driver)
vehicles: Vehicle[];
@OneToMany(() => Member, member => member.driver)
members: Member[];
}
here's an example of how driver would look
Ma buddy i dont want to have a one to many... i need a one to one
Your ERD shows one to many
No |- is a one to one
MANY
Thats how its interpreted
I was looking at the wrong part mb
import { Entity, PrimaryGeneratedColumn, Column, OneToOne } from "typeorm";
import { Vehicle } from "../vehicle/vehicle.entity";
@Entity()
export class Driver {
@PrimaryGeneratedColumn()
driver_id: number;
@Column()
driver_name: string;
@Column()
driver_number: string;
@Column()
driver_region: string;
@OneToOne(() => Vehicle, vehicle => vehicle.driver)
vehicle: Vehicle;
}
Try this
I already did that